home *** CD-ROM | disk | FTP | other *** search
/ JCSM Shareware Collection 1993 November / JCSM Shareware Collection - 1993-11.iso / cl720 / qbnws31j.lzh / QBNWS301.NWS < prev    next >
Text File  |  1992-03-29  |  133KB  |  2,892 lines

  1.      Volume  3, Number  1                                    March 29, 1992
  2.  
  3.      
  4.      
  5.      
  6.      
  7.      
  8.      
  9.      
  10.      
  11.      
  12.      
  13.      
  14.      
  15.                    **************************************************
  16.                    *                                                *
  17.                    *                    QBNews                      *
  18.                    *                                                *
  19.                    *      International QuickBASIC Electronic       *
  20.                    *                  Newsleter                     *
  21.                    *                                                *
  22.                    *    Dedicated to promoting QuickBASIC around    *
  23.                    *                  the world                     *
  24.                    *                                                *
  25.                    **************************************************
  26.      
  27.      
  28.      
  29.      
  30.      
  31.      
  32.      
  33.      
  34.      
  35.      
  36.      
  37.      
  38.      
  39.      
  40.      
  41.      
  42.         The  QBNews  is  an electronic newsletter  published  by  Clearware
  43.      Computing. It can be freely distributed providing NO CHARGE is charged
  44.      for  distribution.  The  QBNews is copyrighted in  full  by  Clearware
  45.      Computing.  The  authors  hold  the  copyright  to  their   individual
  46.      articles.  All program code appearing in QBNews is released  into  the
  47.      public  domain.   You  may  do what you  wish  with  the  code  except
  48.      copyright  it.  QBNews  must  be  distributed  whole  and  unmodified.
  49.      
  50.      You can write The QBNews at:
  51.      
  52.           The QBNews
  53.           P.O. Box 507
  54.           Sandy Hook, CT 06482
  55.      
  56.      Copyright (c) 1992 by Clearware Computing.
  57.      
  58.      The QBNews                                                   Page    i
  59.      Volume  3, Number  1                                    March 29, 1992
  60.  
  61.      
  62.  
  63.      ----------------------------------------------------------------------
  64.  
  65.                         T A B L E   O F   C O N T E N T S
  66.  
  67.      
  68.      1.  From the Editor's Desk
  69.           BASIC Alternatives by David Cleary ...........................  1
  70.           Receiving The QBNews .........................................  3
  71.           Submitting Articles to The QBNews ............................  3
  72.  
  73.      2.  The News Desk
  74.           Goings On in the World of BASIC 
  75.             Crescent Software Expands BBS Service ......................  5
  76.             Microsoft Expands Technical Support on Compuserve ..........  5
  77.             Microhelp Announces Network Library ........................  6
  78.             EllTech Announces Printer Plus .............................  6
  79.             Microsoft Announces the Visual Basic Professional Toolkit ..  6
  80.             Desaware Announces CCF-Cursors for Visual Basic ............  7
  81.             Index Manager Now Available for Visual Basic and PowerBASIC.  7
  82.  
  83.      3.  Microsoft BASIC PDS 7.1
  84.           Converting ASM String Functions to BASIC 7.X by Jay Munro ....  9
  85.           Using Stub Files to Reduce EXE Size by David Cleary .......... 13
  86.           Using Overlays in Microsoft BASIC PDS 7.1 .................... 20
  87.  
  88.      4.  The QBNews Professional Library
  89.           Thanks for the Memories by Robin Duffy ....................... 23
  90.  
  91.      5.  QBASIC Corner
  92.           Extending the QBasic Interpreter by Brent Ashley ............. 28
  93.  
  94.      6.  Swap Shop - QB Source Code Exchange
  95.           Creating Vertical Menus by Bernard Veerman ................... 35
  96.           Windowing in BASIC by Mark Butler ............................ 38
  97.           Viewing Files in BASIC by Matt Hart .......................... 38
  98.  
  99.      7.  Algorithms
  100.           QuickInsert Sort Algorithm -a push from B$ASSN by Larry Stone  39
  101.  
  102.      8.  Fun and Games
  103.           Having A Ball - Solution to 12 Ball Problem .................. 43
  104.  
  105.      9.  The QBNews Volume 2 Annual Index .............................. 45
  106.  
  107.  
  108.  
  109.  
  110.  
  111.  
  112.  
  113.  
  114.  
  115.  
  116.  
  117.  
  118.  
  119.      The QBNews                                                   Page   ii
  120.      Volume  3, Number  1                                    March 29, 1992
  121.  
  122.  
  123.  
  124.      ----------------------------------------------------------------------
  125.                    F r o m   t h e   E d i t o r ' s   D e s k
  126.      ----------------------------------------------------------------------
  127.  
  128.      BASIC Alternatives by David Cleary
  129.      
  130.      It seems to be in vogue today to bash Microsoft. This is undoubtably
  131.      because they have become the predominant software company in most
  132.      areas of computing. BASIC programmers biggest complaint is the fact
  133.      that QuickBASIC 4.5 has not been updated for some four years. They say
  134.      that Microsoft is insensitive to their customers needs. However, since
  135.      QuickBASIC 4.5, Microsoft has released BASIC PDS 7.1 and Visual Basic
  136.      1.0. Microsoft is the only major compiler vendor with a BASIC compiler
  137.      and has proven their commitment to BASIC in my eyes. Although PDS 7.1
  138.      addresses many of the features request for QuickBASIC, the fact that
  139.      it is a professional compiler and is priced like one leaves this out
  140.      as an option.
  141.      
  142.      However, all is not lost. Even though you won't be able to find a
  143.      Borland or Watcom BASIC, there are a number of smaller software
  144.      companies that do provide BASIC compilers. If you feel Microsoft is
  145.      unresponsive to your needs, has lousy tech support, or has abandoned
  146.      the DOS market, then do yourself a favor and check out one of these
  147.      BASIC alternatives.
  148.      
  149.      ZBASIC-PC/386 
  150.      ==============
  151.      32 Bit Software  800-322-4879  $149.95
  152.      
  153.      BB Progression/3
  154.      =================
  155.      Basis International  800-423-1394  $199.95
  156.      
  157.      Thoroughbred BASIC
  158.      ===================
  159.      Concept Omega Corp  800-524-0430  $600 - $900
  160.      
  161.      Workstation BASIC 
  162.      ==================
  163.      Emphasys Software  800-972-2742  $695
  164.      
  165.      GFA BASIC for MS-DOS 
  166.      =====================
  167.      GFA Software Technologies  800-766-6432  $235
  168.      
  169.      387 BASIC
  170.      ==========
  171.      Microway  508-746-7341  $250
  172.      
  173.      NKR BASIC 
  174.      ==========
  175.      NKR Research  408-249-2612  $295
  176.      
  177.      
  178.  
  179.      The QBNews                                                     Page  1
  180.      Volume  3, Number  1                                    March 29, 1992
  181.  
  182.      Power BASIC
  183.      ============
  184.      Spectra Publishing  800-245-6717  $129
  185.      
  186.      True BASIC
  187.      ===========
  188.      True BASIC  800-872-2742  $99.95
  189.      
  190.      In future issues of The QBNews, I hope to have in depth reviews of
  191.      some of these products. In the mean time, give these companies a call
  192.      and ask for some product literature. You may find a product you like
  193.      much better than QuickBASIC.
  194.      
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205.  
  206.  
  207.  
  208.  
  209.  
  210.  
  211.  
  212.  
  213.  
  214.  
  215.  
  216.  
  217.  
  218.  
  219.  
  220.  
  221.  
  222.  
  223.  
  224.  
  225.  
  226.  
  227.  
  228.  
  229.  
  230.  
  231.  
  232.  
  233.  
  234.  
  235.  
  236.      The QBNews                                                     Page  2
  237.      Volume  3, Number  1                                    March 29, 1992
  238.  
  239.      Receiving The QBNews
  240.      
  241.           The  QBNews is distributed mainly through BBS systems around  the
  242.      world.  Some  of  the networks it gets  distributed  through  are  SDS
  243.      (Software   Distribution   System) and  PDN  (Programmers Distribution
  244.      Network). Ask the  sysop of your  local  board about these networks to
  245.      see if there is a  node  in your area.
  246.      
  247.           The  QBNews  can  also  be found  on  CompuServe  in  the  MSLang
  248.      (Microsoft  Language)  forum. It can be found in file area 1 or  2  of
  249.      that  forum. Just search for the keyword QBNEWS. The QBNews will  also
  250.      be available on PC-Link. I send them to Steve Craver, who is the BASIC
  251.      Programming  Forum Host on PC-LINK and he will make them available.  I
  252.      would appreciate anybody who could upload The QBNews to other services
  253.      such as GENIE since I don't have access to these.
  254.      
  255.           I  have also set up a high speed distribution network for  people
  256.      who  would  like to download The QBNews at 9600  baud.  The  following
  257.      boards allow first time callers download privileges also. They are:
  258.      
  259.          Name           Sysop       Location       Number         Node #
  260.      ---------------------------------------------------------------------
  261.      
  262.      Treasure Island  Don Dawson    Danbury, CT    203-791-8532   1:141/730
  263.      
  264.      Gulf Coast BBS   Jim Brewer New PortRichey,FL 904-563-2547   1:365/12
  265.      
  266.      221B Baker St.   James Young   Panama City,FL 904-871-6536   1:3608/1
  267.      
  268.      EMC/80           Jim Harre     St. Louis, MO  314-843-0001   1:100/555
  269.      
  270.      Apple Capitol BBS Bob Finley   Wenatchee, WA  509-663-3618   1:344/61
  271.      
  272.      RadioLink!       Steve Craver  Columbus, OH   614-766-2162   1:226/140
  273.      
  274.      MedTechNet       Bill Hliwa    Buffalo, NY    716-688-1552   1:260/10
  275.      
  276.      
  277.           Finally, you can download The QBNews from these vendors BBS's:
  278.      
  279.      The Crescent Software Support BBS   203-426-5958
  280.      
  281.      The EllTech Support BBS             404-928-7111
  282.      
  283.      The Microhelp BUG BBS               404-552-0567
  284.                                          404-594-9625
  285.      
  286.      
  287.      You do not have to be a customer of these vendors in order to download
  288.      The  QBNews, but the Microhelp BBS only allows non-members 15  minutes
  289.      of time per call.
  290.      
  291.         If you would like to receive The QBNews on disk, I offer a yearly
  292.      subscription for $20.00. This includes four disks containing each
  293.      
  294.      The QBNews                                                     Page  3
  295.      Volume  3, Number  1                                    March 29, 1992
  296.  
  297.      issue as it is published. If you would like a disk with all the back
  298.      issues of The QBNews, please enclose an additional $5.00. The pricing
  299.      structure is as follows:
  300.      
  301.      Base Price for 1 Year -       $20.00
  302.      Disk with Back Issues -        $5.00
  303.      3.5" disk surcharge -          $5.00
  304.      Canada and Mexico surcharge -  $5.00
  305.      All other foreign orders -    $10.00
  306.      
  307.           The  base price includes 5.25" 360k disks. Send a check or  money
  308.      order in U.S. funds to:
  309.      
  310.           The QBNews
  311.           P.O. Box 507
  312.           Sandy Hook, CT 06482
  313.      
  314.           Please  be  sure  to specify what archive format  you  want.  The
  315.      QBNews normally uses PKZip as it's archiver.
  316.      
  317.      ----------------------------------------------------------------------
  318.      Submitting Articles to The QBNews
  319.      
  320.           The QBNews relies on it's readers to submit articles. If you  are
  321.      interested in submitting an article, please send a disk of Ascii  text
  322.      of no more than 70 characters per line to:
  323.      
  324.           The QBNews
  325.           P.O. Box 507
  326.           Sandy Hook, CT 06482
  327.      
  328.      Articles can also be submitted via E-Mail. Send them via Compuserve to
  329.      76510,1725 or via FidoNet to 1:141/777. I can be reached at the  above
  330.      addresses as well as on Prodigy as HSRW18A.
  331.      
  332.      
  333.  
  334.  
  335.  
  336.  
  337.  
  338.  
  339.  
  340.  
  341.  
  342.  
  343.  
  344.  
  345.  
  346.  
  347.  
  348.  
  349.  
  350.  
  351.      The QBNews                                                     Page  4
  352.      Volume  3, Number  1                                    March 29, 1992
  353.  
  354.  
  355.  
  356.      ----------------------------------------------------------------------
  357.                             T h e   N e w s   D e s k
  358.      ----------------------------------------------------------------------
  359.  
  360.      Goings On in the World of BASIC
  361.      
  362.      CRESCENT SOFTWARE EXPANDS BBS SERVICE
  363.      ======================================
  364.      
  365.      Crescent Software has expanded the Crescent Software Support BBS.
  366.      Crescent Software customers can now subscribe for enhanced technical
  367.      support through their BBS. Subscribers can download the latest
  368.      versions of all the Crescent Software products they own, plus receive
  369.      the kind of technical support that isn't possible over the phone such
  370.      as help modifying routines. The service costs $59 per year. You can
  371.      call Crescent Software at 800-35-BASIC, or 203-438-5300. All
  372.      QuickBASIC users are encouraged to call The Crescent Software Support
  373.      BBS at 203-426-5958 - 14.4K v.32bis.
  374.      
  375.      
  376.      MICROSOFT EXPANDS TECHNICAL SUPPORT ON COMPUSERVE
  377.      ==================================================
  378.      
  379.      Microsoft has reorganized all their tech support for software
  380.      developers under a new forum. The new forum is called Microsoft
  381.      Developers Services (GO MSDS).
  382.      
  383.      Specifically, the Microsoft Developer Services area offers: 
  384.      
  385.      - Developer Forums. This set of forums covers information on Windows,
  386.      languages, tools, and utilities from a developers perspective. You can
  387.      use these forums to exchange messages with experienced Microsoft users
  388.      and Microsoft Developer Support engineers.
  389.      
  390.      - Developer Knowledge Base. This up-to-date reference tool contains
  391.      technical information about Microsoft developer specific products
  392.      compiled by Microsoft Product Support. The Knowledge Base is full-text
  393.      searchable, and in addition to technical articles contains special
  394.      information regarding product bug lists, fix lists, documentation
  395.      errors, and Microsoft press releases. 
  396.      
  397.      - Software Library. A collection of binary files, sample code,
  398.      technical specification and utilities. The entire library is
  399.      keyword-searchable, and the files can be downloaded for use locally. 
  400.      
  401.      - Suggestion/Problem Report Form. This form can be used to make
  402.      product suggestions or to report a problem with a Microsoft product.
  403.      
  404.      - Microsoft Service Requests. Microsoft now offers an optional,
  405.      private (fee-based per incident) technical support offering to help
  406.      solve your more complex development problems.
  407.      
  408.      Robert Eineigl, Microsoft Support Engineer (CIS ID 76701,156) explains
  409.      what this means to BASIC programmers - "The restructuring will
  410.      
  411.      The QBNews                                                     Page  5
  412.      Volume  3, Number  1                                    March 29, 1992
  413.  
  414.      positively impact QB users in at least two ways: The concentration of
  415.      resources on the Knowledge Base will mean faster updates and one-stop
  416.      browsing for all developer-related issues.  And finally Basic
  417.      developers/programmers, by being included with the more "stylish"
  418.      development languages, will garner more respect and attention to their
  419.      efforts. This move should be seen as MS's becoming more aware of and
  420.      committed to the importance of CIS as a support delivery medium."
  421.      
  422.      
  423.      MICROHELP ANNOUNCES NETWORK LIBRARY
  424.      ====================================
  425.      
  426.      Microhelp is now shipping the Microhelp Network Library, with versions
  427.      for both QuickBASIC/PDS 7.1 and Visual Basic. The Network Library is
  428.      designed to provide an easy to use wrapper for the network interface
  429.      routines. The library supports Novell, LANtastic, and NetBIOS
  430.      networks. The Microhelp Network Library costs $89 per version, or $169
  431.      for both the QB/VB library and one set of documentation. You can call
  432.      Microhelp at 800-922-3383 or 404-594-1185 for more information or to
  433.      order this product.
  434.      
  435.      
  436.      ELLTECH ANNOUNCES PRINTER PLUS
  437.      ===============================
  438.      
  439.      EllTech is now shipping the new Printer Plus library. Printer Plus
  440.      allows BASIC programmers to support over 400 printers without changing
  441.      a single line of source code. Printer Plus's features include:
  442.      
  443.      - Over 50 text printing functions that allow you to control exactly
  444.      how your printed reports will look regardless of the printer used.
  445.      
  446.      - Utilize advanced features found in modern printers while not
  447.      precluding the use of printers without those features.
  448.      
  449.      - Utilities are provided that allow you to add new printer
  450.      descriptions to our database or edit existing descriptions.
  451.      
  452.      Printer Plus has a list price of $249, but if you order before April
  453.      30, 1992, you can get it for $199. You can call EllTech at
  454.      800-553-1327 or 404-928-8960.
  455.      
  456.      
  457.      MICROSOFT ANNOUNCES THE VISUAL BASIC PROFESSIONAL TOOLKIT
  458.      ==========================================================
  459.      
  460.      "The Professional Toolkit for Visual Basic makes incredibly powerful
  461.      functionality and the latest and greatest Windows operating system
  462.      features accessible to programmers at all levels," said Michael Risse,
  463.      product manager, Professional Toolkit for Visual Basic, at Microsoft.
  464.      "The unique custom control mechanism in Visual Basic makes these
  465.      features as accessible as the click of a mouse." 
  466.      
  467.      Combining the Professional Toolkit with Visual Basic provides a
  468.      
  469.      The QBNews                                                     Page  6
  470.      Volume  3, Number  1                                    March 29, 1992
  471.  
  472.      single-source solution for a broad range of full-featured
  473.      Windows-based applications. Professional programmers can use it to
  474.      enhance existing applications created with Visual Basic as well as to
  475.      create new ones.
  476.      
  477.      The new features include controls to enhance applications with the
  478.      following technologies:
  479.      
  480.      - Object linking and embedding technology (OLE). Microsoft's OLE
  481.      technology lets developers easily create applications that can combine
  482.      spreadsheet, word processing, graphics and other OLE server
  483.      functionality into an application that's customized for specific
  484.      business uses.
  485.      
  486.      - Pen-based computing. Programmers can extend their current
  487.      applications -- or write entirely new ones -- for Microsoft Windows
  488.      for Pen Computing.
  489.      
  490.      - Multimedia. Developers now can easily write or enhance applications
  491.      for Microsoft Multimedia Extensions version 1.0, including video,
  492.      animation, CD-quality audio and other multimedia elements.
  493.      
  494.      - Graphing. Pie and bar charts in 2-D or 3-D, in addition to nine
  495.      other charting styles, can now be added to applications easily with a
  496.      complete graphics package in the Professional Toolkit.
  497.      
  498.      - Grids. Information can be presented in a table complete with
  499.      resizeable rows, columns and scroll bars. This makes the display of
  500.      tabular data a snap for programmers.
  501.      
  502.      - Multiple Document Interfaces (MDI). The MDI control allows the
  503.      developer working with Visual Basic to create applications with
  504.      multiple child windows that are contained in a single parent form.
  505.      
  506.      In addition, the Professional Toolkit gives programmers easy access to
  507.      the following tools and features:
  508.      
  509.      - More than 15 new controls, including 3-D interface components;
  510.      animated buttons, gauges and spin buttons; and access to commonly used
  511.      dialog boxes.]
  512.      
  513.      - The Windows Help Compiler, to create the custom, online Windows Help
  514.      files that users of Windows now expect in their applications.
  515.      
  516.      - The Windows API Online Reference, an accessible guide to Windows
  517.      application programming interfaces (APIs) that makes it easier for
  518.      programmers to maximize their use of Windows.
  519.      
  520.      - A setup kit that helps developers create standard installation
  521.      programs for their applications, plus sample applications, bitmaps and
  522.      a business clip-art library.
  523.      
  524.      - Custom Control Development Kit.
  525.      
  526.      
  527.      The QBNews                                                     Page  7
  528.      Volume  3, Number  1                                    March 29, 1992
  529.  
  530.      The Professional Toolkit for Visual Basic is available now for the
  531.      suggested retail price of $299.  Microsoft Visual Basic with
  532.      Professional Toolkit is available for the suggested retail price of
  533.      $495. For a limited time, owners of Visual Basic can receive the
  534.      Professional Toolkit for a special price of $99.
  535.      
  536.      
  537.      DESAWARE ANNOUNCES CCF-CURSORS FOR VISUAL BASIC
  538.      ================================================
  539.      
  540.      Desaware is now shipping CCF-Cursors, a product that permits the
  541.      creation of custom cursors or mouse pointers for Visual Basic. Over 50
  542.      sample cursors and two demo programs are provided. Also, CCF-Cursors
  543.      also comes with the CCMOUSE custom control. This control supports
  544.      detection of mouse events for any Visual Basic control, including
  545.      those that do not normally detect mouse events. CCF-Cursors lists for
  546.      $35 and is available now by calling Desaware at 408-377-4770.
  547.      
  548.      
  549.      INDEX MANAGER NOW AVAILABLE FOR VISUAL BASIC AND POWER BASIC
  550.      =============================================================
  551.      
  552.      Index Manager, the popular B+ Tree file manager for QuickBASIC has
  553.      been enhanced to support both Visual Basic and PowerBASIC. These two
  554.      new versions boast simple, one-function construction for ease of use
  555.      are written in assembler for small and fast performance. Index Manger
  556.      lists for $99 for the single user version and $250 for the network
  557.      version. Call CDP Consultants at 800-876-0098 for more information or
  558.      to place an order.
  559.      
  560.  
  561.  
  562.  
  563.  
  564.  
  565.  
  566.  
  567.  
  568.  
  569.  
  570.  
  571.  
  572.  
  573.  
  574.  
  575.  
  576.  
  577.  
  578.  
  579.  
  580.  
  581.  
  582.  
  583.  
  584.      The QBNews                                                     Page  8
  585.      Volume  3, Number  1                                    March 29, 1992
  586.  
  587.  
  588.  
  589.      ----------------------------------------------------------------------
  590.                   M i c r o s o f t   B A S I C   P D S   7 . 1
  591.      ----------------------------------------------------------------------
  592.  
  593.      Converting ASM String Functions to BASIC 7.X by Jay Munro
  594.      
  595.      Life was easy when QuickBASIC only had one kind of variable length
  596.      string and it was always in DGroup.  QuickBASIC used Near Strings with
  597.      descriptors in a simple format--two bytes as the length, and two bytes
  598.      as the offset into the String Segment, or DGroup.  That all changed
  599.      with BASIC 7.x PDS.
  600.      
  601.      While the Near String format still lives on with BASIC 7.x as a
  602.      compiler option, the QBX environment requires your assembler functions
  603.      to use Far Strings. The Far Strings data is located in segments other
  604.      than DGroup, with several to choose from. The Main module strings and
  605.      string arrays have one 64k segment, procedure level simple strings and
  606.      temporary strings share another 64k segment, and Common strings are in
  607.      yet a third 64k segment.  That's a lot of space, but it does
  608.      complicate working with strings.
  609.      
  610.      To begin with, the string and array descriptors for all strings are
  611.      kept in DGroup, regardless of where the data is stored.  This is
  612.      important to keep in mind when working with Far Strings, since it is
  613.      still possible to run out of DGroup before you run out of Far String
  614.      space.  Having the descriptors in DGroup let you pass the string to an
  615.      assembler routine as a Near Pointer, just as in earlier versions of
  616.      QuickBASIC.   
  617.      
  618.      The real differences between Near and Far Strings become apparent once
  619.      inside the assembler routine.  To get the length of a Near String, the
  620.      first two bytes of the descriptor are the length.  With Far Strings,
  621.      the pointer (or address) to the descriptor is pushed and the
  622.      StringLength function is called. Stringlength returns the length of
  623.      the string in AX.  In our Trim routine, we move AX into CX for use in
  624.      the loop later. 
  625.      
  626.      For a Near String descriptor, the second two bytes of the descriptor
  627.      point to the string data that is stored in DGroup.  To get the address
  628.      of Far String Data, the desciptor is again pushed and the
  629.      StringAddress function is called.  The StringAddress function returns
  630.      the address of the string as a Far Pointer in DX:AX.  An interesting
  631.      undocumented side effect of StringAddress is that CX contains the
  632.      length when it returns, along with the address in DX:AX.  Microsoft
  633.      will not confirm this, and cautions against depending on undocumented
  634.      features because they are subject to change, but it does work in both
  635.      BASIC 7.0 and 7.1.  You can decide for yourself if you want to drop
  636.      StringLength.
  637.      
  638.      When StringAddress and StringLength are called, SS, BP, DS, SI, and DI
  639.      registers are preserved, but ES is not.  You can see when running a
  640.      program under Codeview that ES returns with the segment of the far
  641.      string after the StringAddress call. Normally this is harmless, but
  642.      when your routine is juggling several incoming strings, ES may be
  643.      
  644.      The QBNews                                                     Page  9
  645.      Volume  3, Number  1                                    March 29, 1992
  646.  
  647.      pointing to another segment.  The trashing of ES may go unnoticed when
  648.      all strings the routine is processing are in the same segment.
  649.      However, if the strings are from different segments, like Common and
  650.      Procedure level strings it becomes apparent.  
  651.      
  652.      The Far string descriptor format also applies to variable length
  653.      string arrays.  To access strings in an array, the VarPtr of the first
  654.      element of the string is passed as shown in the following code
  655.      snippet, and the pointer is incremented by 4 to get each successive
  656.      string.  The function AddEll adds up the lengths of the strings in the
  657.      array$().
  658.      
  659.      '--- BASIC code
  660.      Declare Function AddEll&(Byval Address%,Byval NumEls%)  
  661.      Dim Array$(1 to 200)
  662.      
  663.      .... (fill array)....
  664.      
  665.      TotalSize& = AddEll&(VARPTR (Array$(1),200)
  666.      
  667.      ;---- assembler code 
  668.      .Model Medium,BASIC
  669.      Extrn StringLength:Proc
  670.      
  671.      .code
  672.      AddEll Proc Uses SI DI, Array:Ptr, NumEls:Word
  673.           Xor  DI,DI               ;use DI to track total lengths
  674.           Mov  CX,NumEls           ;get numels (byval remember)
  675.           Jcxz Exit                ;jump out if 0 els
  676.           Mov  SI,Array            ;get pointer to first descriptor
  677.      CountLoop:
  678.           Push CX                  ;preserve CX through count loop
  679.           Push SI                  ;push pointer 
  680.           Call StringLength        ;get length
  681.           Add  DI,AX               ;add length to counter
  682.           Pop  CX
  683.           Add  SI,4                ;point to next 4 byte descriptor
  684.           Loop CountLoop           ;keep going til' done
  685.      Exit:
  686.           Xor  DX,DX               ;clear DX to return long
  687.           Mov  AX,DI               ;and return total count in AX
  688.           Ret
  689.      AddEll EndP
  690.      End
  691.      
  692.      For QB45 or Near Strings, the code can be much more compact, and
  693.      thereby faster.
  694.      
  695.      ;near String version
  696.      AddEll Proc, Array:Ptr, NumEls:Word
  697.           Xor  AX,AX               ;use AX to track total lengths
  698.           Mov  CX,NumEls           ;get numels (byval remember)
  699.           Jcxz Exit                ;jump out if 0 els
  700.           Mov  BX,Array            ;get pointer to first descriptor
  701.      
  702.      The QBNews                                                     Page 10
  703.      Volume  3, Number  1                                    March 29, 1992
  704.  
  705.      CountLoop:
  706.           Add  AX,[BX]             ;first word of is length
  707.           Add  BX,4                ;point to next 4 byte descriptor
  708.           Loop CountLoop           ;keep going til' done
  709.      Exit:
  710.           Xor  DX,DX               ;clear DX to return long
  711.           Ret
  712.      AddEll EndP
  713.      End
  714.      
  715.      Now that we've discussed retrieving Far String information, let's move
  716.      on to our last subject--Far String Functions. 
  717.      
  718.      
  719.      STRING FUNCTIONS
  720.      
  721.      Far String Functions are only a little more complex than their Near
  722.      String counterparts.  In a Near String function, the four byte
  723.      descriptor (LENGTH:ADDRESS) is created in DGroup, as is the data that
  724.      the address points to.  With Far Strings, the four byte descriptor
  725.      must still be in DGroup, but the data can be in any segment.  Unlike
  726.      Near String descriptors which are created by the programmer, the four
  727.      byte descriptor is created by calling BASIC's StringAssign function.  
  728.      
  729.      StringAssign is called with the Length, Segment and Address of the
  730.      data you want to assign, and the Length, Segment and address of the
  731.      destination.  The StringAssign function can assign both variable
  732.      length and fixed length strings.  With fixed length strings,
  733.      StringAssign uses the length parameter on the destination.  When
  734.      assigning a variable length string, the destination length is set to
  735.      zero so StringAssign knows to create a descriptor and store the date.
  736.      The accompanying program, ZeroTrim illustrates the technique.   
  737.      
  738.      There are two caveats to be aware of when using Far Strings and
  739.      StringAssign.  First, when StringAssign is called with the address of
  740.      the descriptor (or destination), it checks to see if the descriptor
  741.      contains a value or not.  If it sees a value, StringAssign assumes it
  742.      is an old descriptor and will try to deallocate the string to make
  743.      room for the new string. On the first entry into your assembler
  744.      function, the descriptor should be null so a new descriptor is
  745.      allocated. However, if your function clears the descriptor between
  746.      calls, BASIC will end up with orphan data from old strings not being
  747.      deallocated.  On the other side, if your program does a CLEAR command
  748.      after a call to a string function, variables on the BASIC side will be
  749.      cleared, but the descriptor stored in your assemblers Data area will
  750.      still exist.  If the assembler routine then calls StringAssign, BASIC
  751.      will try to deallocate the data and you'll end up with a String Space
  752.      Corrupt message.  The rule is don't call Clear once the program
  753.      starts, and don't clear the descriptor between calls. 
  754.      
  755.      If your program needs to free up the space, you may call the
  756.      StringRelease function to deallocate the descriptor.  This is only
  757.      recommended if the function is not going to be called again, since
  758.      StringAssign will always release the old string before assigning a new
  759.      
  760.      The QBNews                                                     Page 11
  761.      Volume  3, Number  1                                    March 29, 1992
  762.  
  763.      one.  The syntax for StringRelease is as follows.
  764.      
  765.      .Data
  766.        Descriptor DD ?
  767.      
  768.      .Code 
  769.      Some Proc ....
  770.      .. 
  771.      .. 
  772.           Push DS
  773.           Push Offset Descriptor
  774.           Call StringRelease
  775.      
  776.           
  777.      Another problem programmers may encounter with Far Strings happens
  778.      when the assigning a zero length string.  Under Near Strings, the
  779.      length portion of the descriptor just zeroed out and BASIC understood.
  780.      Far Strings are not quite so simple, but the concept is similar.
  781.      Though there are several ways to do it, the most reliable is to be to
  782.      point to an actual data area and tell StringAssign that the length is
  783.      zero. StringAssign will then deallocate the old descriptor if there is
  784.      one, and allocate a new one that BASIC recognizes as a zero length
  785.      string.  Again, it is important to let BASIC go through the motions so
  786.      it deallocates the old strings.
  787.      
  788.      As you can see, the conversion of assembler routines from Near Strings
  789.      to Far Strings is not too difficult.  By using the Far String function
  790.      and watching your registers, the transition is almost painless.  Once
  791.      a routine is converted to handle Far Strings, it may be used with
  792.      either BC 7.x compiler option. The Far String functions are
  793.      automatically replaced with near string code when you leave off the
  794.      /FS switch, eliminating the need for two version of the routines for
  795.      BASIC 7 support.  If you need to support QuickBASIC 4.x, you will need
  796.      a second version for near strings only.  
  797.      
  798.      SOURCE CODE FOR THIS ARTICLE CAN BE FOUND IN FARSTRNG.ZIP
  799.      
  800.      ======================================================================
  801.      Jay Munro is a programmer at Crescent Software and also writes
  802.      utilities for PC Magazine in his spare time. He was given the task of
  803.      converting Crescent's QuickPak Pro to use Farstrings, and more
  804.      recently, converting QuickPak Pro for use in Visual Basic.  Jay can be
  805.      contacted through The Crescent Software Support BBS at 203-426-5958,
  806.      or in care of this newsletter.
  807.      ======================================================================
  808.      
  809.  
  810.  
  811.  
  812.  
  813.  
  814.  
  815.  
  816.  
  817.      The QBNews                                                     Page 12
  818.      Volume  3, Number  1                                    March 29, 1992
  819.  
  820.      Using Stub Files to Reduce EXE Size by David Cleary
  821.      
  822.      Microsoft BASIC Professional Development System version 7.1 comes with
  823.      many "stub" files to help reduce the size of your EXE programs. By
  824.      linking with these stub files under certain conditions, you will see
  825.      reductions in EXE size of 2 - 15K. However, improperly using stub
  826.      files may result in your EXE actually getting larger.
  827.      
  828.      Because of the complexity of the BASIC run time libraries, many times
  829.      routines will be included in your EXE even though they are never used.
  830.      For instance, when you do this:
  831.      
  832.      OPEN A$ FOR RANDOM AS #1
  833.      
  834.      the compiler doesn't know if A$ is referring to a file, or to the
  835.      communications port. Therefore, the compiler has no choice but to
  836.      include all the code to handle the communications port. What a stub
  837.      file does, in this instance NOCOM.OBJ, is replace the code that is not
  838.      needed with an empty procedure. This causes all external references
  839.      to be resolved and cause a decrease in EXE size.
  840.      
  841.      The tricky part is figuring out when to use them. For instance, if you
  842.      changed A$ in the example above to:
  843.      
  844.      OPEN "C:\INFO.DAT" FOR RANDOM AS #1
  845.      
  846.      the compiler knows you want to open a file. It will not include the
  847.      communications routines in your EXE file. If you try and link with
  848.      NOCOM.OBJ, you will actually see an increase in EXE size.
  849.      
  850.      There are two types of stub files provided with PDS 7.1. The first
  851.      type is used with stand alone programs (compiled with /O) are are used
  852.      to reduce the size of your EXE file. They include:
  853.      
  854.      NOCGA, NOEGA, NOOGA, NOHERC, NOVGA, NOGRAPH  Graphics stub files
  855.      NOCOM, NOLPT  Device support stub files
  856.      SMALLERR  Error message stub file
  857.      87.LIB  Floating point emulation stub file
  858.      NOEMS, OVLDOS21  Overlay support stub files
  859.      NOFLTIN  Floating point input support stub file
  860.      NOEDIT  INPUT editting functions stub file
  861.      TSCNIO  Text output stub file
  862.      NOTRNEMx.LIB  Transcendental operation stub file
  863.      
  864.      The second type of stub file is used when creating custom run time
  865.      libraries. They do not decrease the size of your EXE file, but rather
  866.      decrease the size of your BRUN file. They include:
  867.      
  868.      NOEVENT  Event trapping stub file
  869.      NOISAM  ISAM support stub file
  870.      
  871.      The following instructions on correctly using these stub files came
  872.      from a file located in the Microsoft Software Library on Compuserve.
  873.      You can access the Microsoft Software Library by typing GO MSDS at any
  874.      
  875.      The QBNews                                                     Page 13
  876.      Volume  3, Number  1                                    March 29, 1992
  877.  
  878.      ! prompt.
  879.      
  880.      When to Use the NOxxx.OBJ Graphics Stub Files
  881.      --------------------------------------------- 
  882.      
  883.      When you code any graphics SCREEN mode, the compiler knows to generate
  884.      code that will require support only for that mode. Therefore, the
  885.      linker will only link in support for the screen mode that you are
  886.      using. If you only use SCREEN 9, the linker will only pull the EGA
  887.      graphics support out of the BASIC libraries.  
  888.      
  889.      The one time when all graphics support will be linked with your
  890.      program is if you use SCREEN with a variable such as the following: 
  891.      
  892.      
  893.         SCREEN X% 
  894.      
  895.      In this case, the compiler does not know what graphics mode you will
  896.      be using until run time. Therefore, it is forced to generate code that
  897.      will cause ALL of the BASIC graphics support to be linked in. In this
  898.      case, you would use NOGRAPH.OBJ, or one or more of the following stub
  899.      files, to stub out support for those modes you will not be using: 
  900.      
  901.      
  902.         NOCGA.OBJ, NOEGA.OBJ, NOOGA.OBJ, NOHERC.OBJ, NOVGA.OBJ 
  903.      
  904.      NOGRAPH.OBJ would only be useful if you are using SCREEN X%, where X%
  905.      is guaranteed to be zero. NOGRAPH.OBJ is only useful when building
  906.      custom run-time modules that will not support graphics. NOGRAPH is a
  907.      superset of all the other above graphics stub files and cannot be
  908.      linked with any of them.  
  909.      
  910.      When to Use NOCOM.OBJ or NOLPT.OBJ
  911.      ----------------------------------
  912.      
  913.      Normally, support for communications or printing will not be linked in
  914.      unless an OPEN "COMx:" or OPEN "LPTx:" statement exists in the
  915.      program. However, if the program contains a statement that resembles
  916.      the following 
  917.      
  918.      
  919.         OPEN A$ FOR <mode> as #n 
  920.      
  921.      then the compiler must assume the A$ might be equal to "COMx:" or
  922.      "LPTx:" at some time during the program. Therefore, communications and
  923.      printing support will be linked in along with all other file support.
  924.      If A$ will never be used to open the "COMx:" port or the printer, then
  925.      the NOCOM.OBJ support module can be used to stub out support for
  926.      communications and NOLPT.OBJ can be used to stub out printer support.
  927.      This should reduce the size of the .EXE program.  
  928.      
  929.      When to Use SMALLERR.OBJ
  930.      ------------------------
  931.      
  932.      
  933.      The QBNews                                                     Page 14
  934.      Volume  3, Number  1                                    March 29, 1992
  935.  
  936.      SMALLERR substitutes smaller error message text strings for the normal
  937.      error messages and maps the BASIC error messages down to a few
  938.      messages. Use this only in a program known to be very stable.  
  939.      
  940.      When to Use 87.LIB
  941.      ------------------
  942.      
  943.      87.LIB could increase the size of the .EXE if the program does not
  944.      contain any math statements at all. However, use the 87.LIB stub file
  945.      (in the .OBJ argument list of LINK, even though it is a .LIB file) to
  946.      decrease the size of the .EXE file when the program contains a math
  947.      statement and will be run ONLY on machines with a math coprocessor.  
  948.      
  949.      When to Use NOEVENT.OBJ
  950.      -----------------------
  951.      
  952.      The NOEVENT.OBJ stub file is useful only to reduce the size of a
  953.      customized run-time module that will not support event trapping.
  954.      NOEVENT.OBJ is NOT useful for reducing the size of your compiled BASIC
  955.      .EXE program.  
  956.      
  957.      If the program can be compiled without /V and /W, the program doesn't
  958.      require event trapping. In this case, mistakenly linking your BASIC
  959.      .OBJ modules directly with NOEVENT.OBJ may increase program size. If
  960.      the program requires /V or /W, you would also not want to link with
  961.      this stub file, since NOEVENT.OBJ is only useful for making customized
  962.      run-time modules.  
  963.      
  964.      When to Use NOEMS.OBJ
  965.      ---------------------
  966.      
  967.      In an overlaid program, this stub file will prevent the overlay
  968.      manager from using expanded memory (EM) even if EM is present. This
  969.      stub could be used if the program needed to use EM for other purposes
  970.      (such as ISAM) and did not want the overlay manager to use EM. This
  971.      stub file reduces code size only by about 1000 bytes. Do not use this
  972.      stub file if the program does not contain overlays or if it is an OS/2
  973.      protected mode program.  
  974.      
  975.      OVLDOS21.OBJ
  976.      ------------
  977.      
  978.      This stub file adds support for DOS version 2.10 to an overlaid
  979.      program. Any overlaid program that would want to work on DOS 2.10 must
  980.      have this file linked with it. OVLDOS21 is not needed (and should not
  981.      be used) if the program is not overlaid or if it is a protected mode
  982.      program. The stub file does not remove code, but always adds code and
  983.      functionality (about 500 bytes).  
  984.      
  985.      When to Use NOFLTIN.OBJ
  986.      -----------------------
  987.      
  988.      Replaces the INPUT code with an "integer only" version. If you link
  989.      with this stub file, all forms of numeric input (INPUT, INPUT #, VAL,
  990.      
  991.      The QBNews                                                     Page 15
  992.      Volume  3, Number  1                                    March 29, 1992
  993.  
  994.      and READ) will have the following restrictions: 
  995.      
  996.      1. READ, INPUT, INPUT #, and VAL will no longer recognize leading base 
  997.         specifiers on numbers. The following specifiers are illegal: 
  998.      
  999.      
  1000.            &H &O, & 
  1001.      
  1002.      2. READ, INPUT, INPUT #, and VAL will no longer recognize trailing 
  1003.         type specifiers on numbers. The following specifiers are illegal: 
  1004.      
  1005.      
  1006.            !, %, #, & and @ 
  1007.      
  1008.      3. READ, INPUT, INPUT #, and VAL will no longer parse a number with 
  1009.         either a decimal point, E, or D in them. Thus, while 1E3 is a legal 
  1010.         BASIC integer, it will not be recognized.  
  1011.      
  1012.      4. Using a SINGLE precision, DOUBLE precision, or CURRENCY variable 
  1013.         with READ, INPUT, INPUT #, and VAL will cause the math support to 
  1014.         be linked in. The restrictions in points 1-3 above will still hold.  
  1015.         Also, using any other math related operation will pull in the 
  1016.         support pack without lifting the restrictions of 1-3.  
  1017.      
  1018.      The main size advantage to using this stub file occurs when READ,
  1019.      INPUT, INPUT#, or VAL are the only statements that use the math
  1020.      package. This stub file will then eliminate at least 11K of code. If
  1021.      some other statement also needs the math package, the savings will be
  1022.      less than 2K.  
  1023.      
  1024.      When to Use NOEDIT.OBJ
  1025.      ----------------------
  1026.      
  1027.      This stub file replaces the editor used with the INPUT and LINE INPUT
  1028.      statements. It removes the following functions from the editor: 
  1029.      
  1030.      1. No control character commands are recognized except for ENTER (done 
  1031.         editing) and BACKSPACE (removes the last character). All other 
  1032.         control characters are ignored, as are INS, DEL, HOME, END, and the 
  1033.         arrow keys. Function keys will still expand because this 
  1034.         functionality is performed outside the INPUT editor.  
  1035.      
  1036.      2. If output is redirected (using >) and input is not redirected (no 
  1037.         <), no characters will be echoed to the screen. The normal INPUT 
  1038.         editor will print the characters as you types them in this 
  1039.         situation.  
  1040.      
  1041.      3. No characters will be echoed to the line printer even if line 
  1042.         printer echoing is turned on.  
  1043.      
  1044.      You can obtain a 1K reduction in .EXE size using this stub file.
  1045.      Linking with this file could increase program size if the program
  1046.      never uses INPUT, LINE INPUT, LINE INPUT #, RANDOMIZE. If the program
  1047.      does not have INPUT or LINE INPUT statements but does have LINE INPUT
  1048.      
  1049.      The QBNews                                                     Page 16
  1050.      Volume  3, Number  1                                    March 29, 1992
  1051.  
  1052.      # or RANDOMIZE (with not parameters), there will still be some
  1053.      savings.  
  1054.      
  1055.      When to Use the TSCNIOxx.OBJ Stub Files
  1056.      --------------------------------------- 
  1057.      
  1058.      Note: The statements affected by this stub file are subject to change
  1059.      in future versions.  
  1060.      
  1061.      The TSCNIOxx.OBJ file provides a smaller, simpler text output package.
  1062.      When it is linked in, the following differences from standard BASIC
  1063.      will occur: 
  1064.      
  1065.      
  1066.       1. No graphics statements are supported. All the following statements 
  1067.          and functions will generate an illegal function call: 
  1068.      
  1069.      
  1070.             CIRCLE, POINT statement, POINT function, PAINT, PSET, VIEW,
  1071.             VIEW SCREEN, WINDOW, PALETTE, PALETTE USING, DRAW,
  1072.             PUT (graphics), LINE, PCOPY, PMAP, GET (graphics)
  1073.      
  1074.      
  1075.       2. VIEW PRINT will not be supported. All programs will have an 
  1076.          implicit VIEW PRINT 1 TO <screen-size - 1> as is the normal 
  1077.          default. For programs linked with this stub file, the only way to 
  1078.          reach the bottom screen line is with the LOCATE statement, since 
  1079.          the VIEW PRINT statement is not available.  
  1080.      
  1081.      
  1082.       3. There will be no support for function key display. The KEY 
  1083.          ON/OFF/LIST statements will generate an illegal function call.  
  1084.          CTRL+T to an INPUT statement will be silently ignored. Softkey 
  1085.          definition and expansion will still be supported.  
  1086.      
  1087.      
  1088.       4. The COLOR statement will not accept a border parameter. Also, the 
  1089.          color parameters are sent directly to the hardware. Thus, on an 
  1090.          EGA or VGA card with a monochrome monitor, many values for COLOR 
  1091.          will cause text to not be visible.  
  1092.      
  1093.      
  1094.       5. Embedded control characters will not be supported for PRINT.  
  1095.          Currently, the following features (which need to be added to the 
  1096.          manual) are supported for the nonstubbed version of the PRINT
  1097.          code:
  1098.      
  1099.      
  1100.          Control 
  1101.          Character   Description 
  1102.          ---------   ----------- 
  1103.      
  1104.      
  1105.          CTRL+G      Beeps the speaker 
  1106.      
  1107.      The QBNews                                                     Page 17
  1108.      Volume  3, Number  1                                    March 29, 1992
  1109.  
  1110.      
  1111.      
  1112.          CTRL+I      Moves the cursor to the next tab position, erasing 
  1113.                      characters 
  1114.      
  1115.      
  1116.          CTRL+J      Moves the cursor to the beginning of the next line 
  1117.      
  1118.      
  1119.          CTRL+K      Moves the cursor to the top-left corner of the current 
  1120.                      VIEW PRINT window 
  1121.      
  1122.      
  1123.          CTRL+L      Clears the VIEW PRINT window, homes the cursor within 
  1124.                      it 
  1125.      
  1126.      
  1127.          CTRL+M      Moves the cursor to the beginning of the next line 
  1128.      
  1129.      
  1130.          CTRL+\      Moves the cursor to the right one space, stopping at 
  1131.                      the end of the line 
  1132.      
  1133.      
  1134.          CTRL+]      Moves the cursor to the left one space, stopping at 
  1135.                      the beginning of the line 
  1136.      
  1137.      
  1138.          CTRL ^      Moves the cursor up one line, stopping at the top of 
  1139.                      the VIEW PRINT window 
  1140.      
  1141.      
  1142.          CTRL_       Move the cursor down one line, stopping at the bottom 
  1143.                      of the VIEW PRINT window 
  1144.      
  1145.      
  1146.       6. The SCREEN and WIDTH statements will not be supported. The program 
  1147.          will use whatever screen mode was available on start-up, unless it 
  1148.          is a graphics mode, in which case an attempt will be made to 
  1149.          determine if any text mode can be run in that graphics mode. The 
  1150.          screen will always be 80 columns, displaying on video page 0. The 
  1151.          number of lines will be determined by start-up conditions. The 
  1152.          screen state will not be restored when the program terminates.  
  1153.      
  1154.      
  1155.       7. CLS will not accept any parameters.  
  1156.      
  1157.      
  1158.       8. Underline cursors on an EGA card not in 25-line mode may not be 
  1159.          handled properly.  
  1160.      
  1161.      
  1162.       9. This stub file may not be used to build a customized run-time
  1163.          module. It may not support the CHAIN statement.
  1164.      
  1165.      The QBNews                                                     Page 18
  1166.      Volume  3, Number  1                                    March 29, 1992
  1167.  
  1168.      
  1169.      10. This stub file does not support CGA snow elimination during screen 
  1170.          output.  
  1171.      
  1172.      This "set" of stub files is dependent upon operating system and
  1173.      near/far string support. Thus, there are four different versions of
  1174.      the file: 
  1175.      
  1176.      
  1177.         File           Description 
  1178.         ----           ----------- 
  1179.      
  1180.      
  1181.         TSCNIONR.OBJ   Near string DOS version 
  1182.         TSCNIOFR.OBJ   Far string DOS version 
  1183.         TSCNIONP.OBJ   Near string OS/2 version 
  1184.         TSCNIOFP.OBJ   Far string OS/2 version 
  1185.      
  1186.      Any program linked with one of these stub files should decrease in
  1187.      size. The size decrease should be between 1.3K and 4.4K depending on
  1188.      the statements used in the program and the library being linked with.  
  1189.      
  1190.      When to Use the NOTRNEMx.LIB Stub File
  1191.      -------------------------------------- 
  1192.      
  1193.      NOTRNEMR.LIB and NOTRNEMP.LIB remove support for transcendental
  1194.      operations, including: SIN, COS, TAN, ATN, LOG, SQR, EXP, ^ (the
  1195.      exponential operator), a CIRCLE statement with a start or stop value,
  1196.      and the DRAW statement with the A or T commands.  
  1197.      
  1198.      When to Use the NOISAM.OBJ Stub File
  1199.      ------------------------------------ 
  1200.      
  1201.      NOISAM.OBJ removes ISAM functionality from customized BASIC run-time
  1202.      modules. NOISAM.OBJ is not useful when linking stand-alone (BC /O)
  1203.      BASIC executable programs.
  1204.      
  1205.      ======================================================================
  1206.      David Cleary is a software engineer for Vectron Laboratories in
  1207.      Norwalk, CT and is also the author of Crescent Software's PDQComm. He
  1208.      can be reached in care of this newsletter, on Compuserve as
  1209.      76510,1725, on Prodigy as HSRW18A, on Fidonet at 1:141/777, and on the
  1210.      Crescent Software Support BBS at 203-426-5958.
  1211.      ======================================================================
  1212.      
  1213.  
  1214.  
  1215.  
  1216.  
  1217.  
  1218.  
  1219.  
  1220.  
  1221.  
  1222.      The QBNews                                                     Page 19
  1223.      Volume  3, Number  1                                    March 29, 1992
  1224.  
  1225.      Using Overlays in Microsoft BASIC PDS 7.1
  1226.      
  1227.      The following information comes directly from The Microsoft Knowledge
  1228.      Base. The Microsoft Kwowledge Base is a huge database of information
  1229.      on all Microsoft products. Microsoft technical support uses the
  1230.      Knowledge Base to help answer your questions. You can access the
  1231.      Knowledge Base yourself through Compuserve. Just type GO MSDS at any !
  1232.      prompt.
  1233.      
  1234.      Title: How to Use Link Overlays in Basic PDS Versions 7.0 and 7.1
  1235.      Document Number: Q51416
  1236.      Publ Date:  7-OCT-1991
  1237.      Product Name: Microsoft BASIC Compiler Product Version:  7.00 7.10
  1238.      Operating System: MS-DOS 
  1239.      
  1240.      Summary:
  1241.      When using the linker (LINK.EXE) to generate code overlays for
  1242.      Microsoft Basic Professional Development System (PDS) version 7.0 or
  1243.      7.1 under MS-DOS, you must put the modules you want to overlay in
  1244.      parentheses on the LINK command line. The modules that make up one
  1245.      overlay must be compiled with the same switches. Code is the only part
  1246.      of the program that is overlaid. Data is not overlaid. Examples and
  1247.      further restrictions for using linker overlays are given below.  This
  1248.      information applies to Microsoft Basic PDS versions 7.0 and 7.1 for
  1249.      MS-DOS (but does NOT apply to earlier Basic compiler versions).  Note
  1250.      that link overlays are not needed and not supported under OS/2
  1251.      protected mode, because OS/2 itself automatically provides a similar
  1252.      feature to support swapping of very large .EXE programs in OS/2
  1253.      extended and virtual memory.
  1254.      
  1255.      More Information:
  1256.      
  1257.      The following is an example of how to produce code overlays:
  1258.         LINK test1+(test2+test3)+test4+(test5)+(test6),TEST1.EXE,TEST1.MAP;
  1259.      where the following apply:
  1260.      
  1261.      1. test1 (TEST1.OBJ) is the main module.
  1262.      2. test2 and test3 (TEST2.OBJ and TEST3.OBJ) are separately compiled
  1263.         modules that make up one overlay.
  1264.      3. test4 (TEST4.OBJ) stays resident in memory along with the main
  1265.         module (test1) at run time and is not swapped out of memory to
  1266.         disk.
  1267.      4. test5 and test6 (TEST5.OBJ and TEST6.OBJ) are two separate
  1268.         overlays.
  1269.      5. TEST1.EXE is the executable overlaid program created by this LINK.
  1270.      6. TEST1.MAP is a text file (created by the above LINK) that tells
  1271.         you the code sizes of all overlays and procedures.
  1272.         
  1273.      To invoke an overlay, you call a SUB or FUNCTION in a module contained
  1274.      in that overlay, and the Overlay Manager automatically moves the
  1275.      overlay (if it is not already loaded) into DOS memory, overlaying any
  1276.      previous overlay in memory.
  1277.      
  1278.      You can call any module or overlay from any other module or overlay.
  1279.      
  1280.      The QBNews                                                     Page 20
  1281.      Volume  3, Number  1                                    March 29, 1992
  1282.  
  1283.      Overlays provide an alternative to CHAINing when a program is too
  1284.      large to fit into memory all at once. An overlaid program is made up
  1285.      of a single .EXE file (which can be an advantage in some cases),
  1286.      unlike CHAINed programs, which are composed of several .EXE files.
  1287.      
  1288.      Restrictions on Using Overlays
  1289.      ------------------------------
  1290.      The restrictions on using overlays in Microsoft Basic PDS versions
  1291.      7.0 and 7.1 for MS-DOS are as follows:
  1292.      
  1293.      1. Each Microsoft Basic overlay cannot exceed 256K in code (see LINK
  1294.         .MAP for size of each overlay). You can have up to 64 overlays
  1295.         per .EXE program. This means you may be able to make .EXE programs
  1296.         up to 16 MB in code size under MS-DOS.
  1297.      2. The main module must be the first module in the LINK command line,
  1298.         and it must NOT be specified as an overlay. If you incorrectly make
  1299.         the first module in the LINK command line an overlay, the machine
  1300.         will hang when the program first loads.
  1301.      3. When you create an overlaid version of a program, make sure that
  1302.         each module contained in the program is compiled with the same
  1303.         options.
  1304.      4. You cannot use the LINK /PACKCODE or /EXEPACK option when linking a
  1305.         program that uses overlays.
  1306.      5. You cannot have a stub file as an overlay. Do not specify stub
  1307.         files (NOxxx.OBJ) in the parentheses for link overlays, or the
  1308.         program will hang. Stub files may only be specified outside
  1309.         parentheses in the LINK command line.
  1310.         
  1311.      Using Expanded Memory with Overlays
  1312.      -----------------------------------
  1313.      
  1314.      386Max (386MAX.SYS) from Qualitas, Inc. is an example of an expanded
  1315.      memory driver that can be used with Basic PDS 7.0 and 7.1. Basic PDS
  1316.      7.0 and 7.1 require an expanded memory driver that uses the
  1317.      Lotus-Intel-Microsoft (LIM) version 4.0 Expanded Memory Specification
  1318.      (EMS).
  1319.      
  1320.      If you have loaded an expanded memory driver, and if all the overlays
  1321.      can fit together at one time in expanded memory, and if each overlay
  1322.      has less than 64K of code, then overlays are loaded from expanded
  1323.      memory. Otherwise, overlays are swapped from disk, which is slower
  1324.      than loading from expanded memory.
  1325.      
  1326.      Assume that the overlaid program satisfies the above conditions for
  1327.      using expanded memory. Note that the overlaid modules are not loaded
  1328.      when the .EXE file is first invoked. They remain on disk until the
  1329.      first overlay is called. When this occurs, all the overlaid modules
  1330.      are loaded at once from disk into expanded memory. From then on, the
  1331.      overlays are swapped from expanded memory into DOS memory, and the
  1332.      disk is no longer used for loading overlays.
  1333.      
  1334.      The overlay manager in Basic 7.0 and 7.1 requests expanded memory in
  1335.      16K pages (blocks). The overlay manager only knows the size of the
  1336.      largest overlay, and must make a "best guess" at the size of the
  1337.      
  1338.      The QBNews                                                     Page 21
  1339.      Volume  3, Number  1                                    March 29, 1992
  1340.  
  1341.      smaller overlays. When the overlay manager estimates how many 16K
  1342.      pages are necessary to hold all overlays at once in expanded memory,
  1343.      the estimate could be over or under the actual number of pages needed.
  1344.      If your overlays are all between 16K and 64K in size (according to the
  1345.      LINK .MAP file), and if the estimated or actual size of all overlays
  1346.      together exceeds the available expanded memory, the following
  1347.      initialization error occurs when the first overlay is called at
  1348.      run-time:
  1349.      
  1350.         Insufficient EMS to load overlays
  1351.         
  1352.      Note: This error is documented on page 656 of the "Microsoft Basic
  1353.      7.0: Language Reference" manual for versions 7.0 and 7.1. You will
  1354.      never see this error if all your overlays are smaller than 16K each.
  1355.      If you want to force loading overlays from disk, thus avoiding the
  1356.      possibility of this overlay initialization error in expanded memory,
  1357.      you must link with the stub file NOEMS.OBJ (with no parentheses around
  1358.      NOEMS.OBJ on the LINK command line). Alternatively, you can try
  1359.      reconfiguring expanded memory so more of it is available for Basic
  1360.      overlays. Another alternative is to make overlays similar in size.
  1361.      
  1362.      DOS Memory Map When Using Overlaid .EXE Program
  1363.      ------------------------------------------------
  1364.      
  1365.      [Low Memory]
  1366.       - MS-DOS
  1367.       - Main program and non-overlaid modules
  1368.       - Contiguous overlay memory area, equal to the size of biggest
  1369.         overlay
  1370.       - DGROUP (default data segment, which is shared by all routines)
  1371.       - Far heap (dynamic non-variable-length-string arrays)
  1372.       - Basic's run-time support module if .EXE not compiled stand-alone
  1373.         (BC /O)
  1374.      [High Memory]
  1375.      
  1376.      For more information on using overlays, see the following:
  1377.      "Microsoft Basic 7.0: Programmer's Guide." pages 612-614.
  1378.      Additional reference words: 7.00 7.10
  1379.      
  1380.      COPYRIGHT Microsoft Corporation, 1991.
  1381.      
  1382.  
  1383.  
  1384.  
  1385.  
  1386.  
  1387.  
  1388.  
  1389.  
  1390.  
  1391.  
  1392.  
  1393.  
  1394.  
  1395.      The QBNews                                                     Page 22
  1396.      Volume  3, Number  1                                    March 29, 1992
  1397.  
  1398.  
  1399.  
  1400.      ----------------------------------------------------------------------
  1401.           T h e   Q B N e w s   P r o f e s s i o n a l   L i b r a r y
  1402.      ----------------------------------------------------------------------
  1403.  
  1404.      Thanks for the Memories by Robin Duffy
  1405.      
  1406.      For years QuickBASIC programmers have done some pretty incredible
  1407.      things when it comes to using all the resources available on a PC. Of
  1408.      all the things accomplished, the ability to use expanded memory was
  1409.      heralded as a major accomplishment (at least I thought it was!). Now
  1410.      QB programmers had oodles more of that precious commodity, RAM! Why,
  1411.      several meg of RAM could now be used by programmers without thinking,
  1412.      allowing them to create the most powerful of applications.
  1413.      
  1414.      Without thinking? Well, not really. Expanded memory has its drawbacks,
  1415.      one of which is the concept of bank switching blocks of this memory in
  1416.      and out of the processor's addressable space.  Also there was no
  1417.      management of these blocks available to the programmer other than what
  1418.      he could muster up for himself. He had to keep track of what data was
  1419.      in what page and which pages were loaded where in the page frame.
  1420.      Without some careful advanced planning it would be easy to get things
  1421.      all mixed up beyond any hope of survival.
  1422.      
  1423.      Another disadvantage I saw was the difficulty in saving a huge array
  1424.      into this 64K page frame. A huge array by definition is larger than
  1425.      the page frame itself. So, one would have to save the first 64K of the
  1426.      array into the four available pages, swap pages, and then save another
  1427.      64K chunk.  I think there is a term for this sort of work around
  1428.      programming - kludge!  Why would you want to have all this beautiful
  1429.      streamlined code in your program and then rely on a kludge?
  1430.      
  1431.      Well, my thoughts took a different course after I tried programming
  1432.      for expanded memory. I knew there was a different sort of memory
  1433.      native to AT machines called extended memory. Extended memory differed
  1434.      from expanded memory in several different ways, the most attractive of
  1435.      which was the fact this memory was continuous for meg after meg. The
  1436.      only problem with this memory was it was only available from the
  1437.      processor's protected mode of operation. Now, I thought, how can I get
  1438.      to this memory from a platform I am comfortable with? The answer was
  1439.      obvious, but somewhat frightening!
  1440.      
  1441.      Now enter a rather mysterious little device driver supplied with many
  1442.      versions of DOS named HIMEM.SYS. HIMEM.SYS was barely documented (if
  1443.      at all) as an extended memory manager, but precious little else could
  1444.      be found out about it. Now here was something that could manage
  1445.      extended memory for me, if only I could find out how to make this
  1446.      thing work!  Expanded memory has this dedicated interrupt (Int 67h)
  1447.      that made interface simple, but HIMEM was written differently.
  1448.      Instead of a clean system of interrupt function calls, or even
  1449.      invoking a device name, HIMEM.SYS is used by calling the driver
  1450.      directly as a procedure call!  While direct calls to device drivers
  1451.      can be done directly from QB with CALL ABSOLUTE, not every aftermarket
  1452.      runtime library supported this QB keyword. Setting up the required
  1453.      structures was also somewhat of a pain. The idea for an assembly
  1454.      
  1455.      The QBNews                                                     Page 23
  1456.      Volume  3, Number  1                                    March 29, 1992
  1457.  
  1458.      interface to HIMEM.SYS was born!
  1459.      
  1460.      HIMEM.SYS provides a variety of functions for managing extended
  1461.      memory, the high memory area (1M + 64K) and the upper memory area
  1462.      (memory between A000:0000 and 1M). It is important for user programs
  1463.      NOT to issue calls for managing the high and UMB memory areas if some
  1464.      other program is already managing those areas, especially DOS.  The
  1465.      popularity of DOS 5.0 meant I would have to be careful which functions
  1466.      I chose to implement. After consideration I chose only those functions
  1467.      that allocate, deallocate, move, and report on extended memory. HIMEM
  1468.      would perform a move to and from conventional memory, so I did not
  1469.      require the use of the other functions.
  1470.      
  1471.      I was pleasantly surprised when I learned HIMEM uses a handle based
  1472.      system for managing blocks of memory instead of a more bulky system
  1473.      such as page frames. For each block of XMS you allocate HIMEM assigns
  1474.      a handle to reference the block by. This allows HIMEM to manage the
  1475.      actual locations any way it pleases in a transparent manner - so if I
  1476.      wanted to allocate a 1.5 meg block of XMS memory (certainly possible)
  1477.      I could reference it at anytime with a single handle.  Certainly an
  1478.      improvement over paging!  Another advantage of handles is a program
  1479.      can use several blocks of XMS memory of varying sizes without regard
  1480.      to the physical location of the memory or what's in it.  Just use the
  1481.      handle much like you would a DOS file handle and let it go at that.
  1482.      
  1483.      There is one responsibility you as programmer must undertake when
  1484.      deciding to use extended memory in your program. You must make sure to
  1485.      release any XMS memory you allocate before your program ends its
  1486.      execution. This memory is not managed by DOS at all, so DOS can not
  1487.      automatically release XMS on program termination as it does for
  1488.      conventional memory. If a program exits without releasing it, the
  1489.      memory remains allocated until the next time the computer is booted!
  1490.      Although the demo program I have included does not do this, you should
  1491.      trap all possible means by which your program can be terminated.
  1492.      
  1493.      Included with this text is my extended memory interface for
  1494.      QuickBASIC, the XMS driver. When designing XMS I had considered using
  1495.      a system of pointers to emulate a block storage device, and using it
  1496.      like a disk drive. However, after some consideration I decided to
  1497.      implement it similar to the manner Ethan Winer had implemented his
  1498.      expanded memory interface for QuickPak Professional.  The major reason
  1499.      for this design decision is simulation of a block device would not
  1500.      remove enough of the management required by the programmer.  I think
  1501.      that although somewhat limited, the XMS driver provides a good amount
  1502.      of flexibilty while insulating the programmer from much of the work
  1503.      involved.
  1504.      
  1505.      Let's now take a look at the ten procedures that make up the XMS
  1506.      driver for QuickBASIC. I won't get into the calling syntax here (it is
  1507.      included as part of the ZIP file in XMS.DOC) but will instead provide
  1508.      some comment on the operation of each. If you wish to see these
  1509.      routines in action just run the small demo program included with the
  1510.      driver package.
  1511.      
  1512.      
  1513.      The QBNews                                                     Page 24
  1514.      Volume  3, Number  1                                    March 29, 1992
  1515.  
  1516.      INITXMS is the procedure to get the ball rolling. This procedure
  1517.      checks for the presence of HIMEM.SYS and determines the availability
  1518.      of XMS memory. This procedure returns the availability and size of any
  1519.      XMS memory on the machine in two integers. The size returned is the
  1520.      actual XMS available in K bytes (that is, this number times 1024 is
  1521.      the actual size).
  1522.      
  1523.      GETXMS is a function that allocates a block of XMS memory and returns
  1524.      its handle.  The only parameter for this function is the size of the
  1525.      memory block you are requesting, in K bytes (1024 bytes is the
  1526.      smallest increment in which HIMEM.SYS will allocate XMS memory).  You
  1527.      may specify a block of any size up to and including all available
  1528.      memory!  Block sizes of several meg are commonplace. If desired, you
  1529.      may specify a number of different blocks for different purposes.
  1530.      
  1531.      FREEXMS will deallocate (free up) memory that was allocated using
  1532.      GETXMS. Simply call it with the handle of the block you wish to
  1533.      release. See the above paragraphs for the importance of using this
  1534.      call.
  1535.      
  1536.      ARRAY2XMS is a procedure that will copy any continuous block of
  1537.      conventional memory to an allocated block of XMS. This procedure will
  1538.      copy the block of conventional memory into the XMS block at offset
  1539.      zero into the block. One interesting use of this procedure is saving
  1540.      huge arrays to XMS with one call. In fact, given enough extended
  1541.      memory, you could conceivably copy the entire contents of conventional
  1542.      memory to XMS! You can use this call with any far array.  The only
  1543.      limitation posed by this procedure is the number of bytes to move must
  1544.      be an even number. Odd numbers are forced even without comment or
  1545.      error.
  1546.      
  1547.      XMS2ARRAY is the compliment routine to ARRAY2XMS. Its function is to
  1548.      copy a block of memory from XMS to conventional memory.  I have used
  1549.      these two routines to save and restore the screen directly from XMS.
  1550.      The only drawback to using this method to save and restore screens is
  1551.      HIMEM.SYS knows nothing of retrace checking for CGA monitors, and may
  1552.      cause some snow.  Other uses include restoring huge arrays with one
  1553.      call and loading code stored in XMS.
  1554.      
  1555.      XGETELEMENT is one of those afterthought routines. If you know the
  1556.      size of the array elements you have stored in an XMS block (and you
  1557.      should), this procedure will allow retrieving a single element from
  1558.      that block. The demo program uses this routine to display any random
  1559.      element the user chooses. The procedure uses your element size and an
  1560.      element number to determine where in the XMS block to start reading.
  1561.      Please note this procedure assumes the first element of your stored
  1562.      array is item number one, not zero. Also, your element size must be an
  1563.      even number.
  1564.      
  1565.      XSETELEMENT is the compliment procedure to XGETELEMENT and has
  1566.      identical syntax. This procedure will allow the setting of any
  1567.      individual element stored in XMS memory. The demo program uses this
  1568.      procedure to change any chosen element to a new value of the user's
  1569.      choice.  These two routines can let you set up a "virtual" array in
  1570.      
  1571.      The QBNews                                                     Page 25
  1572.      Volume  3, Number  1                                    March 29, 1992
  1573.  
  1574.      extended memory of any element size, up to and including all installed
  1575.      XMS!
  1576.      
  1577.      Next come three procedures that deal with error handling.  These
  1578.      procedures were inspired by Ethan's QuickPak Professional and really
  1579.      bind the whole thing together. My personal salute to Ethan Winer for
  1580.      such insightful design!
  1581.      
  1582.      XMSERROR is a function that will return the current state of error,
  1583.      but not the specific error code. This is extremely handy when you wish
  1584.      to test for an error condition, but don't care what error has
  1585.      occurred. Very neat code can be written for error handling as so:
  1586.      
  1587.                .
  1588.                .
  1589.            CALL Array2XMS(SEG Array%(start%), XHandle%, NumBytes&)
  1590.            IF XMSError% THEN
  1591.                PRINT "Error transferring array to XMS"
  1592.                (branch to error handling code here)
  1593.            ELSE
  1594.                PRINT "Array transferred"
  1595.            END IF
  1596.                .
  1597.                .
  1598.      
  1599.      The status of errors is updated after every call in this driver except
  1600.      for INITXMS. Thus, any sucessful operation will clear the value of any
  1601.      previous error.
  1602.      
  1603.      It should be noted that if XMS memory is not available for any reason
  1604.      (such as HIMEM not installed, extended memory not installed or none
  1605.      available) this function will always show an error condition.  This
  1606.      way programming logic will not have to adapt much to the presence or
  1607.      lack of XMS memory.
  1608.      
  1609.      WHICHXERROR is a function that will return the actual code of an error
  1610.      reported by XMSError. This routine would most likely be used inside an
  1611.      error handling routine to determine the course of action required by
  1612.      the program. If there is no outstanding error condition WhichXError
  1613.      will return a zero.
  1614.      
  1615.      WhichXError is designed so if XMS memory is not available for any
  1616.      reason this function will always return a "Function not supported"
  1617.      error. I thought it might cause some confusion if a call to a routine
  1618.      in this driver fails because XMS is not available and the reported
  1619.      error was "No Error"!
  1620.      
  1621.      SETXERROR is a sub you can use to set the error code returned by
  1622.      WhichXError. This sub will allow setting error codes in the range of 0
  1623.      to 255 inclusive. I thought for completeness this procedure should be
  1624.      included. I also thought about allowing this sub to work if no XMS is
  1625.      installed but then decided against it. Again, some confusion could
  1626.      result if you set the error code to zero when no XMS was installed.
  1627.      So, if XMS is not available to the driver, this sub will have no
  1628.      
  1629.      The QBNews                                                     Page 26
  1630.      Volume  3, Number  1                                    March 29, 1992
  1631.  
  1632.      effect on anything.
  1633.      
  1634.      Well, that pretty much wraps it up. Included with the XMS package is a
  1635.      sample program and source code that demomstrates use of most of the
  1636.      routines in this package. One glaring error that stands out is a
  1637.      CRTL-C will abort this program prematurly (it uses standard DOS I/O so
  1638.      it can be interrupted easily) and lose the allocated memory until next
  1639.      reboot. I did this intentionally so you could see the results of such
  1640.      a programming practice. If you experiment, you'll see that when you
  1641.      try to run the demo again, it will tell you there is no available XMS
  1642.      memory!
  1643.      
  1644.      These routines have been tested pretty thoroughly, but not completely.
  1645.      It is after all just a prototype for something normally not possible
  1646.      within a QuickBASIC program. I hope it provides you with many hours of
  1647.      entertainment just pushing the driver to the limits!
  1648.      
  1649.      I have only scratched the surface of the potential of this driver.  I
  1650.      am sure there are hundreds (perhaps thousands) of practical
  1651.      applications for blocks of memory larger than those you can access by
  1652.      any other means except straight protected mode programming.  I would
  1653.      be interested to learn just what feats can be accomplished using this
  1654.      code as a starting point.
  1655.      
  1656.      If you have any comments concerning the XMS driver package or would
  1657.      like to ask me a question concerning it, feel free to contact
  1658.      Sequental Software's support BBS at (606) 561-5766 24 hours daily.
  1659.      There's no registration fee and you get full privs on the first call.
  1660.      I'm usually on it every day, so your question should be answered in
  1661.      about 24 hours or so. If you are more inclined to write, send your
  1662.      response to:
  1663.      
  1664.                Sequential Software Inc.
  1665.                P.O. Box 53
  1666.                Somerset, KY 42502-0053 USA
  1667.      
  1668.      Make sure to put it to my attention. I will answer as soon as possible
  1669.      by mail.
  1670.      
  1671.      Have fun and good luck!
  1672.      
  1673.      SOURCE CODE FOR THIS ARTICLE CAN BE FOUND IN XMS.ZIP
  1674.  
  1675.  
  1676.  
  1677.  
  1678.  
  1679.  
  1680.  
  1681.  
  1682.  
  1683.  
  1684.  
  1685.  
  1686.      The QBNews                                                     Page 27
  1687.      Volume  3, Number  1                                    March 29, 1992
  1688.  
  1689.  
  1690.  
  1691.      ----------------------------------------------------------------------
  1692.                             Q B A S I C   C o r n e r
  1693.      ----------------------------------------------------------------------
  1694.  
  1695.      Extending the QBasic Interpreter by Brent Ashley
  1696.      
  1697.      With the widespread acceptance of MS-DOS 5.0, many people are
  1698.      discovering and rediscovering the power of modern, structured BASIC.
  1699.      This is evidenced especially in the various BBS network programming
  1700.      echoes, where very often a reply is now prefaced with:
  1701.      
  1702.        "Well, if by QBasic you mean the one that came with DOS 5.0 then 
  1703.        I'm afraid that can't be done; but if you mean the QuickBASIC 
  1704.        compiler, well then you simply..."
  1705.      
  1706.      QBasic (the interpreter) differs from QB (the QuickBASIC compiler) in
  1707.      a few ways, but mostly in its extensibility, or more to the point,
  1708.      lack of it.  Keen QBasic programmers soon run up against the
  1709.      language's limitations, mostly as regards system-level programming.
  1710.      While the obvious solution would be to buy QuickBASIC for its access
  1711.      to DOS and BIOS interrupts and its easy extensibility via code
  1712.      libraries, in many situations this is impractical.  Perhaps your
  1713.      company MIS department disallows language purchases by "common users"
  1714.      (I hear bells ringing in heads all over the continent as you read
  1715.      this!), or your personal budget doesn't allow for it yet.  It would be
  1716.      best to use a company-sanctioned tool, or one you already have, if
  1717.      only it provided the functionality you needed.
  1718.      
  1719.      One advanced feature Microsoft "left in" the QBasic interpreter is the
  1720.      CALL ABSOLUTE statement.  This statement allows you to call a
  1721.      machine-language routine at a known place in memory, and to pass it a
  1722.      list of arguments.  At first glance it doesn't seem to be of much use,
  1723.      but with a little imagination, you can use this feature to extend the
  1724.      use of QBasic far into QB's realm.
  1725.      
  1726.      I have written three assembly-language routines which, together with
  1727.      their BASIC support routines, add the following to the QBasic arsenal:
  1728.      
  1729.      o    DOS and BIOS Interrupt calls
  1730.      o    Almost instant memory block copies
  1731.      o    Fast colour single-line box drawing
  1732.      
  1733.      You will find these routines with ASM source, along with a demo
  1734.      program containing many sample QBasic support routines, in QBASIC.ZIP.
  1735.      Meanwhile, I'll explain here the methods I use to load and call binary
  1736.      routines and some of the further-reaching implications.  Keep in mind
  1737.      that all of these routines work just as well with the QuickBASIC
  1738.      compiler, as long as the CALL ABSOLUTE routine from QB.LIB is
  1739.      available.
  1740.      
  1741.      I'll try to encapsulate the essence of loading and calling a BIN file
  1742.      from QBasic in a short example.  This example program uses the
  1743.      MEMCOPY.BIN file to quickly copy a block of memory so screen saves can
  1744.      be done without PCOPY, which isn't supported by monochrome adapters.
  1745.      
  1746.      The QBNews                                                     Page 28
  1747.      Volume  3, Number  1                                    March 29, 1992
  1748.  
  1749.      The source is followed by a discussion of its innards.
  1750.      
  1751.      -------------- ASM Source ---------------------------------------
  1752.      ; MemCopy.ASM - by Brent Ashley
  1753.      ; Copies blocks of memory quickly
  1754.      ; - to be used primarily for screen saves.
  1755.      ;
  1756.      .MODEL medium, BASIC
  1757.      .CODE
  1758.      MemCopy PROC USES si di ds es, \
  1759.                   FromSeg:PTR WORD, FromOfs:PTR WORD, \
  1760.                   ToSeg:PTR WORD, ToOfs:PTR WORD, \
  1761.                   Count:PTR WORD
  1762.          ; load ds:si with source, es:di with destination 
  1763.          mov bx,FromOfs
  1764.          mov si,[bx]
  1765.          mov bx,ToSeg
  1766.          mov es,[bx]
  1767.          mov bx,ToOfs
  1768.          mov di,[bx]
  1769.          mov bx,Count
  1770.          mov cx,[bx]
  1771.          ; ds last (used to access data)
  1772.          mov bx,FromSeg
  1773.          mov ds,[bx]
  1774.          ; do the copy 
  1775.          cld
  1776.          rep movsb
  1777.          ret
  1778.      MemCopy  ENDP
  1779.      END
  1780.      
  1781.      --------------- QBasic code --------------------------------------
  1782.      DEFINT A-Z
  1783.      DECLARE FUNCTION LoadBin$ (BinFileName$)
  1784.      
  1785.      CLS
  1786.      FOR i = 1 TO 24                        ' fill screen with letters
  1787.        PRINT STRING$(80, 64 + i);
  1788.      NEXT
  1789.      ScrnSave 1                             ' save screen
  1790.      SLEEP 1                                ' wait a second for user to see screen
  1791.      CLS
  1792.      PRINT "That screenful of letters has been erased."
  1793.      PRINT : PRINT "Press a key to restore screen..."
  1794.      DO: LOOP UNTIL LEN(INKEY$)             ' wait for key
  1795.      ScrnSave 0                             ' restore screen
  1796.      END
  1797.      
  1798.      SUB ScrnSave (SaveRestore) STATIC
  1799.        ' save/restore a text screen
  1800.        ' save = nonzero, restore = 0
  1801.        STATIC InitDone, ScrnBuf, VidSeg     ' ensures local scope
  1802.        IF NOT InitDone THEN
  1803.      
  1804.      The QBNews                                                     Page 29
  1805.      Volume  3, Number  1                                    March 29, 1992
  1806.  
  1807.          REDIM ScrnBuf(1 TO 2000)           ' 4000 bytes (80x25x2)
  1808.          DEF SEG = 0
  1809.          IF PEEK(&H463) = &HB4 THEN         ' determine mon/colour
  1810.            VidSeg = &HB000 ' mono
  1811.          ELSE
  1812.            VidSeg = &HB800 ' colour
  1813.          END IF
  1814.          DEF SEG
  1815.          InitDone = -1
  1816.        END IF
  1817.        IF SaveRestore THEN                  ' save
  1818.          BlockCopy VidSeg, 0, VARSEG(ScrnBuf(1)), VARPTR(ScrnBuf(1)), 4000
  1819.        ELSE                                 ' restore
  1820.          BlockCopy VARSEG(ScrnBuf(1)), VARPTR(ScrnBuf(1)), VidSeg, 0, 4000
  1821.        END IF
  1822.      END SUB
  1823.      
  1824.      SUB BlockCopy (FromSeg, FromOfs, ToSeg, ToOfs, Count)
  1825.        ' copy a block of memory 
  1826.        STATIC MemCopy$                      ' ensure local scope
  1827.        IF NOT LEN(MemCopy$) THEN MemCopy$ = LoadBin("MemCopy.BIN")
  1828.        DEF SEG = VARSEG(MemCopy$)           ' point to routine's segment
  1829.        CALL Absolute(FromSeg, FromOfs, ToSeg, ToOfs, Count, SADD(MemCopy$))
  1830.      END SUB
  1831.      
  1832.      FUNCTION LoadBin$ (BinFileName$)
  1833.        ' Loads a binary file as a string
  1834.        STATIC FileNum, Buf$
  1835.        FileNum = FREEFILE
  1836.        OPEN BinFileName$ FOR BINARY AS FileNum
  1837.        IF LOF(FileNum) = 0 THEN             ' file didn't exist
  1838.          CLOSE FileNum
  1839.          KILL BinFileName$
  1840.          CLS : PRINT "Can't find "; BinFileName$; " - aborting."
  1841.          END
  1842.        END IF
  1843.        Buf$ = SPACE$(LOF(FileNum))          ' size buffer
  1844.        GET FileNum, , Buf$                  ' load BIN routine
  1845.        CLOSE #FileNum
  1846.        LoadBin$ = Buf$
  1847.      END FUNCTION
  1848.      
  1849.      --------------------- end of example --------------------------------
  1850.      
  1851.      The Assembly routine was written with Microsoft's QuickAssembler.  I
  1852.      used some of its advanced segment directives and high-level language
  1853.      interface capabilities, but knowledgeable (read:masochistic)
  1854.      programmers could generate similar .BIN files with DEBUG as long as
  1855.      they were familiar with accessing stack parameters and cleaning up the
  1856.      stack on return.  All it does is to load DS:SI and ES:DI with the
  1857.      source and destination and then copy the number of bytes specified by
  1858.      Count, which is in the range 0 to 65535.  The routine is assembled and
  1859.      then converted to binary image with EXE2BIN.  The resulting file is
  1860.      called MEMCOPY.BIN.
  1861.      
  1862.      The QBNews                                                     Page 30
  1863.      Volume  3, Number  1                                    March 29, 1992
  1864.  
  1865.      
  1866.      The QBasic code consists of a short main module which fills the
  1867.      screen, saves it, erases it, and restores it, using our routine.
  1868.      While only the ScrnSave procedure is called by the demo, ScrnSave
  1869.      relies on BlockCopy, which in turn relies on LoadBIN$.
  1870.      
  1871.      ScrnSave saves and restores the screen by reserving a block of memory
  1872.      to use as a buffer.  This allows fast screen saves on monochrome
  1873.      adapters, which do not have extra video pages as do colour adapters.
  1874.      The first time the routine is called, it dimensions the buffer array
  1875.      and determines the adapter type and therefore the address of the
  1876.      screen page.  Then, and on any subsequent calls, it copies the the
  1877.      screen contents between the buffer and screen memory, depending on the
  1878.      value of SaveRestore.
  1879.      
  1880.      The BlockCopy routine performs the copy requested by ScrnSave.  On
  1881.      first pass, it loads the ASM routine from its .BIN file on disk into
  1882.      the string MemCopy$, which has been declared as STATIC.  The STATIC
  1883.      declaration causes it to retain its value between calls ensures it
  1884.      isn't affected by any module-level variable of the same name which may
  1885.      have been declared with the SHARED attribute.  It then uses the CALL
  1886.      ABSOLUTE statement to call the BIN routine.  This is done by setting
  1887.      BASIC's current DEF SEG to the routine's segment and then passing the
  1888.      address of the routine to run, along with the parameters to pass.  It
  1889.      is interesting to note that CALL ABSOLUTE takes a variable number of
  1890.      parameters, depending on the requirements of your routine.  Note that
  1891.      SADD is used to determine the address of the routine, since it is
  1892.      stored in a string variable.
  1893.      
  1894.      LoadBin$ is a general-purpose function to load these .BIN files from
  1895.      disk into a string.  It assumes the file is in the current directory
  1896.      or that the path is specified in BinFileName$.  The file is loaded
  1897.      into a string which is then returned by the function, to be called
  1898.      with CALL ABSOLUTE by your QBasic-level support routine.
  1899.      
  1900.      Using the methods demonstrated in this example, it is possible to
  1901.      extend QBasic's power as far as your assembly skills allow.  It is
  1902.      even possible to write support routines which would allow the creation
  1903.      and use of BIN libraries.  I had contemplated doing this but decided
  1904.      that interest wouldn't be high enough due to the availability of the
  1905.      QuickBASIC compiler, and the fact that  multiple BIN files in a
  1906.      "library" directory would be simple enough to implement under the
  1907.      scheme outlined above.
  1908.      
  1909.      There are some details and implications of the BIN routine methods
  1910.      described above which aren't readily apparent.
  1911.      
  1912.      Firstly, in exploring the CALL ABSOLUTE assembly interface, one will
  1913.      soon discover that FUNCTIONs are not readily supported.  The simple
  1914.      solution to this will serve to exemplify an important aspect of
  1915.      QBasic/BIN programming - the QBasic "front-end" routine.
  1916.      
  1917.      We met the front-end routine in our example program, in the guise of
  1918.      the BlockCopy routine.  This routine served to insulate our main
  1919.      
  1920.      The QBNews                                                     Page 31
  1921.      Volume  3, Number  1                                    March 29, 1992
  1922.  
  1923.      program from the details of loading and calling the BIN file.  It was
  1924.      called with only the parameters relevant to the task at hand, and in
  1925.      turn called the ABSOLUTE routine with the additional BIN-file specific
  1926.      parameters.
  1927.      
  1928.      Since the front-end file takes care of some of the dirty details of
  1929.      BIN file calls in easy-to-code-and-maintain QBasic, we can simplify
  1930.      the assembly routine, often the hardest to write and most difficult to
  1931.      maintain part of the hybrid program.
  1932.      
  1933.      Take the example of a routine which uses the BIOS to print a
  1934.      character.  In QBasic, we would like to pass to the routine the
  1935.      character, its positional row and column on the screen, and the 
  1936.      foreground and background colours in which to print the character.  
  1937.      Our calls to this routine might look like this:
  1938.      
  1939.      BIOSPrint Char$, Row%, Col%, Fore%, Back%
  1940.      
  1941.      Anyone who has written assembly routines for BASIC will attest to the
  1942.      hassles involved in accessing BASIC's dynamic strings.  It would be
  1943.      nice to write the routine to receive the ASCII value of the character
  1944.      instead as an integer.  Furthermore, the BIOS routines use 0-based
  1945.      screen positioning, as opposed to the 1-based positioning used in
  1946.      QBasic.  To insulate the user from confusion, the routine should
  1947.      adjust QBasic row and column values to BIOS values, and even build
  1948.      them into a single integer to be loaded into a register for the BIOS
  1949.      call.  Lastly, the BIOS routine will want a single integer colour
  1950.      attribute, meaning you will have to program the conversion routine if
  1951.      the separate colours are sent.  Really, then, the BIN routine really
  1952.      wants the parameters sent like this:
  1953.      
  1954.      CALL ABSOLUTE(AsciiValue%, BIOSPosition%, Attribute%, BINAddress%)
  1955.      
  1956.      Your front-end routine, then, can take care of all of these
  1957.      conversions, thus minimising the assembly code so it performs only
  1958.      that which QBasic can't do for itself:
  1959.      
  1960.      SUB BIOSPrint (Char$, Row%, Col%, Fore%, Back%)
  1961.         STATIC BINFile$
  1962.         IF BINFile$ = "" THEN BINFile$ = LoadBinFile("BIOSPRT.BIN")
  1963.         AsciiValue% = ASC(Char$)
  1964.         BIOSPosition% = (Row% - 1) * 256 + (Col% - 1)
  1965.         Attribute% = (Fore% AND 16) * 8 + (Back% AND 7) * 16 + (Fore% AND 16)
  1966.         DEF SEG VARSEG(BINFile$)
  1967.         CALL ABSOLUTE(AsciiValue%, BIOSPosition%, Attribute%, SADD(BINFile$))
  1968.      END SUB
  1969.      
  1970.      The front-end routine also answers the FUNCTION problem.  Here is the
  1971.      code for a fictitious CurDrive function which would act identically to
  1972.      the one in the QBIN demo program:
  1973.      
  1974.      FUNCTION CurDrive%
  1975.        STATIC BinFile$
  1976.        ' returns logged drive (a=1, b=2, etc)
  1977.      
  1978.      The QBNews                                                     Page 32
  1979.      Volume  3, Number  1                                    March 29, 1992
  1980.  
  1981.        IF BinFile$ = "" THEN BINFile$ = LoadBinFile("CurDrv.BIN")
  1982.        AXReg% = 0
  1983.        DEF SEG VARSEG(BinFile$)
  1984.        CALL ABSOLUTE(AXReg%, SADD(BinFile$))
  1985.        CurDrive% = AXReg% MOD 256 + 1
  1986.      END FUNCTION
  1987.      
  1988.      Since you can't return values to CALL ABSOLUTE in the same way you
  1989.      would when writing assembly FUNCTIONs for compiled QuickBASIC, you
  1990.      have to provide your assembly routine with references to variables to
  1991.      be changed and then use the front-end routine to pass them to the
  1992.      caller via a FUNCTION.
  1993.      
  1994.      The second point I'd like to make is more far-reaching and has much
  1995.      more potential for power -  the use of strings containing BIN files as
  1996.      parameters to your BASIC routines.
  1997.      
  1998.      Anyone who has used Nantucket's Clipper 5.x product will know the
  1999.      power of "code blocks".  These are sections of code which can be
  2000.      assigned to a variable and passed between routines like data.
  2001.      Actually, the code is static in memory and the routines receive
  2002.      references, but knowledge of these details is not necessary.  In this
  2003.      way (among others), the Clipper implementation differs from that of C
  2004.      and PASCAL, for instance, where you use "pointers to functions", which
  2005.      demand that you dwell on some of these details directly.
  2006.      
  2007.      Let's say you want to write a generic sort routine.  You want it to
  2008.      support ascending and descending sorts, as well as sorting starting at
  2009.      a certain column of the input strings.
  2010.      
  2011.      The normal way to do this would be to provide a passed argument
  2012.      specifying which of the hard-wired methods to use, for example:
  2013.      
  2014.      CALL SortArray ( Array$(), TypeOfSort% )
  2015.      
  2016.      Deeper inside the routine, you would have code similar to:
  2017.      
  2018.      SUB SortArray (...
  2019.      ...
  2020.      SELECT CASE TypeOfSort% ' choose hard-wired method
  2021.        CASE 1 ' ascending
  2022.          IF Array$(i) < Array$(j) THEN SWAP Array$(i), Array$(j)
  2023.        CASE 2 ' descending
  2024.          IF Array$(i) > Array$(j) THEN SWAP Array$(i), Array$(j)
  2025.        CASE 3 ' sort from column 5 ascending
  2026.          IF MID$(Array$(i),5) < MID$(Array$(j),5) THEN SWAP ...
  2027.          ...etc
  2028.      
  2029.      If you were to write a series of ASM routines, however, each of which
  2030.      took two string parameters, performed a comparison according to your
  2031.      latest whim, and returned a true-or-false value, then saved these as
  2032.      BIN files, you could simplify your routine to:
  2033.      
  2034.      Compare$ = LoadBINFile( "MyAsmFn.BIN" )
  2035.      
  2036.      The QBNews                                                     Page 33
  2037.      Volume  3, Number  1                                    March 29, 1992
  2038.  
  2039.      
  2040.      CALL SortArray ( Array$(), Compare$ )
  2041.      
  2042.      SUB SortArray (...
  2043.      ...
  2044.        IF CallBINFunc(Compare$, Array$(i), Array$(j)) THEN SWAP ...
  2045.      
  2046.      You and your users can now write ASM modules yourselves to your specs
  2047.      and extend the functionality of your routine without touching its
  2048.      innards.
  2049.      
  2050.      You could also use this method to send a user-defined filter condition
  2051.      to your display routine, or to tell an event handling routine what to
  2052.      do when it is triggered - all completely extensible without
  2053.      recompiling your main code or even having access to source!
  2054.      
  2055.      Unfortunately, the kind of flexibility that would really make these
  2056.      methods shine (access to QBasic variables, definition of code blocks
  2057.      in QBasic itself, pointers to functions...) isn't available with
  2058.      external BIN files.  Perhaps Microsoft has been thinking of something
  2059.      like this for the future?  I would be interested in anyone's ideas on
  2060.      how to expand on these concepts.  
  2061.      
  2062.      I can be found lurking about many QuickBASIC conferences on the
  2063.      various BBS networks, including Fido's QUIK_BAS echo, ILink, RelayNet
  2064.      (RIME), and NorthAmeriNet (NANET). Feel free to drop by and say hello.
  2065.      
  2066.      SOURCE CODE FOR THIS ARTICLE CAN BE FOUND IN QBASIC.ZIP
  2067.      
  2068.      ======================================================================
  2069.      Brent Ashley is a Technical Support Analyst for the Ontario
  2070.      Government, troubleshooting a province-wide data communications
  2071.      network and providing hardware and software support to a 24-hour
  2072.      micro/mainframe helpdesk operation. He can be reached in care of this
  2073.      newsletter.
  2074.      ======================================================================
  2075.      
  2076.  
  2077.  
  2078.  
  2079.  
  2080.  
  2081.  
  2082.  
  2083.  
  2084.  
  2085.  
  2086.  
  2087.  
  2088.  
  2089.  
  2090.  
  2091.  
  2092.  
  2093.      The QBNews                                                     Page 34
  2094.      Volume  3, Number  1                                    March 29, 1992
  2095.  
  2096.  
  2097.  
  2098.      ----------------------------------------------------------------------
  2099.       S w a p   S h o p   -   Q B   S o u r c e   C o d e   E x c h a n g e
  2100.      ----------------------------------------------------------------------
  2101.  
  2102.      Creating Vertical Menus by Bernard Veerman
  2103.      
  2104.      You don't always need a complex set of routines to perform WINDOW like
  2105.      techniques. To avoid confusion with the word WINDOWS, from hereon I'll
  2106.      use the buzzwords TABLES and PAGES. As a matter of fact, the basics do
  2107.      have things in common, but I prefer to keep things clear (and fast). I
  2108.      need tables in my programs like files, text and directories. These I
  2109.      want to display, move forwards and backwards through it, select and
  2110.      pick an item and that's it. The programming for that I did myself, be-
  2111.      cause I couldn't find any flexible and uncomplicated software. What is
  2112.      left, are some powerful subprograms that might be used by itself or
  2113.      may be added to a (personal) library. The "tables" are made reentrant,
  2114.      that means: use the table as you wish, destroy the existing screen and
  2115.      recall the table any time you need it. The advantage is, the table
  2116.      attributes and pointers are popped from a stack and allow you to con-
  2117.      tinue where you left off. Want to relocate the table, just open it
  2118.      again and tell it where to pop up. Basically there is nothing more than
  2119.      2 calls:
  2120.      
  2121.      TABLOPEN, pushes attributes and pointers to an internal stack;
  2122.      TABLSLCT, displays the table and handles keystrokes.
  2123.      
  2124.      the syntax of both functions is:
  2125.      
  2126.      TABLOPEN TNR, ROW, COL, HGT, WID, SF, SB, BF, BB, TY$
  2127.      
  2128.      TNR = table number, in this example valid between 1 and 6.
  2129.            Array TablDefs could be part of your library.
  2130.      
  2131.      ROW = row where table is to be displayed on the screen. If you intent
  2132.            to use a frame around your tablepage, ROW is the display line
  2133.            where the frame will start. Height and Width are adjusted by the
  2134.            function.
  2135.      
  2136.      COL = column where table is to be displayed on the screen. See ROW for
  2137.            comments on Height and Width.
  2138.      
  2139.      HGT = is tableheight in lines. Validation is left out the program to
  2140.            keep the coding simple and clear. You may add validation if you
  2141.            wish, it won't be difficult. HGT will be 2 less if a frame is
  2142.            used.
  2143.      
  2144.      WID = is tablewidth in characters. Also no validation, same as HGT.
  2145.            WID also will be 2 less if a frame is used.
  2146.      
  2147.      FS  = foreground color of screen. See COLOR instructions as explained
  2148.            in your DOS manual. VZCOLORS.BAS includes the dutch names for
  2149.            colors, brightness and blinking. No validation is done on colors
  2150.            escpecially equal fore- and background colors might cause confu-
  2151.            sion. Something like black characters on a black background. If
  2152.      
  2153.      The QBNews                                                     Page 35
  2154.      Volume  3, Number  1                                    March 29, 1992
  2155.  
  2156.            you do this careful, you will have no problems.
  2157.      
  2158.      BS  = background color of screen. See FS parameter.
  2159.      
  2160.      FB  = foreground color of bar. The bar will run up and down over the
  2161.            table entries and is advised to have a different color than the
  2162.            screen to make it visible.
  2163.      
  2164.      BB  = background color of bar. See FB parameter.
  2165.            
  2166.      TY$ = type of frame, if you need one. "" (null string or character)
  2167.            means that you don't want a frame. "S" will create a single
  2168.            line frame, "D" a double. Lowercase is allowed. In the coding
  2169.            you find a routine called DRAWBOX as you'll find in any library,
  2170.            so if you have one of your, than use it.
  2171.      
  2172.      After declaration of your table(s) nothing happens until you call the
  2173.      table handler TABLSLCT. Since all attributes and pointers are pushed
  2174.      on the stack TablDefs, it simply uses the table number to pop them
  2175.      back to where you need them. All, except two (PTR and CUR), are
  2176.      treated as CONSTANTS until you change them. PTR and CUR are saved as
  2177.      soon as you leave the table handler for further use. The table handler
  2178.      returns them when you access the table again. This is one of the nicer
  2179.      features, because in this way tables are reentrant. For a good impres-
  2180.      sion of how things work, look in the example program where you find
  2181.      the 3 OPEN's and then how they are used.
  2182.      
  2183.      
  2184.      The full syntax of the table handler is:
  2185.      
  2186.      TABLSLCT TNR, Table$(), Entry$
  2187.      
  2188.      TRN      = table number, between 1 and 6, by using this number you will
  2189.                 make the table handler refer to the stack entry where attri-
  2190.                 butes and pointers for this table are stored.
  2191.      
  2192.      Table$() = name of the table you want to use. The table must be decla-
  2193.                 red with a DIM statement and filled with the data you want
  2194.                 to be handled by the table handler.
  2195.      
  2196.      Entry$   = will return your pick from the table or "<ESCAPE>" if you
  2197.                 used the escape key. This is very convenient if you need
  2198.                 to know if an escape was used.
  2199.      
  2200.      
  2201.      The table handler uses a couple of functions and a stack to store the
  2202.      attributes and pointers. The stack and the internal subprograms are
  2203.      strongly advised to integrate in a (personal) library so that you
  2204.      don't have to worry about these things when you're using the table
  2205.      handler. So again convenience is very important. Just fancy this:
  2206.      
  2207.      DIM Titles$(250)
  2208.      now fill array with data
  2209.      TABLOPEN 1, 250, 6, 60, 16, 20, WT, ZW, ZW, WT, "S"
  2210.      
  2211.      The QBNews                                                     Page 36
  2212.      Volume  3, Number  1                                    March 29, 1992
  2213.  
  2214.      TABLSLCT 1, Titles$(), Book$
  2215.      
  2216.      now, talking about powerful programming! To explain these statements
  2217.      in brief:
  2218.      
  2219.      DIM Titles$(250)              allocate array for 250 titles
  2220.                  fill array with titles
  2221.      TABLOPEN 1, 200, 6, 60, 16, 20, WT, ZW, ZW, WT, "S"
  2222.      |        |  |    |  |   |   |   |       |       --- single line frame
  2223.      |        |  |    |  |   |   |   |       +----- bar: black on white
  2224.      |        |  |    |  |   |   |   +----- screen: white on black
  2225.      |        |  |    |  |   |   +--- table with 20, including frame
  2226.      |        |  |    |  |   +--- table height 16, including frame
  2227.      |        |  |    |  +--- column to display table
  2228.      |        |  |    +--- row to display table
  2229.      |        |  +--- actual number of entries used in array Titles$
  2230.      |        +--- table number in stack TablDefs
  2231.      +--- call to declare table
  2232.      
  2233.      TABLSLCT TNR, Titles$(), Book$
  2234.      |        |    |          ------- returns your pick or "<ESCAPE>"
  2235.      |        |    +--- tell table handler to pick from array Titles$
  2236.      |        +--- use attributes and pointers as declared for table 1
  2237.      +--- call table handler
  2238.      
  2239.      In a matter of facts, this is all you have to do. The demo-program
  2240.      shows how you can use the table handler. To summarize, for the user
  2241.      two sub programs are called to handle tables:
  2242.      
  2243.      1. TABLOPEN
  2244.      2. TABLSLCT
  2245.      
  2246.      the table handler itself uses some internal subprograms and needs a
  2247.      stack to store the attributes an pointers, they are:
  2248.      
  2249.      1. TablDefs(), reasonable dimension is (6, 12).
  2250.      2. DRAWBOX or any other similar function.
  2251.      3. TABLDISP, this one displays a table page.
  2252.      4. TABLLINE, this one switches lines from normal to reversed video
  2253.                   and back.
  2254.      5. TABLLOAD, this copies the attributes and pointers to the handler.
  2255.      
  2256.      SOURCE CODE FOR THIS ARTICLE CAN BE FOUND IN TABLE.ZIP
  2257.      ======================================================================
  2258.      Bernard Veerman is a professional IT staff member at Amsterdam 
  2259.      Schiphol Airport in the Netherlands. He has been using QuickBASIC
  2260.      since version 2.0, and has a number of shareware utilities available.
  2261.      He can be reached at the following address:
  2262.      Bernard Veerman
  2263.      Donizettihof 5
  2264.      2402 EH  ALPHEN ad RIJN
  2265.      NETHERLANDS
  2266.      ======================================================================
  2267.      
  2268.      The QBNews                                                     Page 37
  2269.      Volume  3, Number  1                                    March 29, 1992
  2270.  
  2271.      Windowing in BASIC by Mark Butler
  2272.      Preface by David Cleary
  2273.      
  2274.      The last issue of The QBNews contained an assembly language windowing
  2275.      library written by Christy Gemmel. This proved to be on of the most
  2276.      popular articles ever in The QBNews. However, some people said "The
  2277.      ASM routines are great, BUT, I program in BASIC and I want to see
  2278.      BASIC routines to do that." You've got your wish. A little while ago,
  2279.      Mark Buttler posted this code in the Fidonet QuickBASIC echo, and I
  2280.      was quick to capture it. It is comprised of three routines. They are:
  2281.      
  2282.      Explode (UpRow%, LCol%, LoRow%, RCol%)
  2283.      Expand (UpRow%, LCol%, LoRow%, RCol%)
  2284.      ScreenClear (LineColor%)
  2285.      
  2286.      They are contained in WINDOW.BAS. Explode will pop a window on the
  2287.      screen instantly. Expand will create a window that expands little by
  2288.      little. ScreenClear is a neat little special effect for clearing the
  2289.      screen. Load WINDOW.BAS up in your QB editor and enjoy.
  2290.      
  2291.      ----------------------------------------------------------------------
  2292.      
  2293.      Viewing Files in BASIC by Matt Hart
  2294.      
  2295.      This is another gem that was posted in the Fidonet QuickBASIC echo by
  2296.      Matt E. Hart, QB Guru (echo joke). It is a complete routine that
  2297.      allows viewing of a text file of up to 16384 lines without the use of
  2298.      temporary files. The routine supports the arrow keys, page up and
  2299.      down, home and end, and escape.
  2300.      
  2301.      ' View any size text file without
  2302.      any temporary files.  ' Keeps the SEEK position of each line in a long
  2303.      integer array - ' which does limit this to 16,384 lines of text (and
  2304.      makes this ' program easy, small, and fast.)  Key controls are up,
  2305.      down, ' left, right, page up, page down, end, home, and escape.
  2306.      Although the program is laid out as a stand alone application, you
  2307.      shouldn't have too much trouble integrating it into your own programs.
  2308.      The code is contained in VIEWFILE.BAS.
  2309.      
  2310.  
  2311.  
  2312.  
  2313.  
  2314.  
  2315.  
  2316.  
  2317.  
  2318.  
  2319.  
  2320.  
  2321.  
  2322.  
  2323.  
  2324.  
  2325.      The QBNews                                                     Page 38
  2326.      Volume  3, Number  1                                    March 29, 1992
  2327.  
  2328.  
  2329.  
  2330.      ----------------------------------------------------------------------
  2331.                                A l g o r i t h m s
  2332.      ----------------------------------------------------------------------
  2333.  
  2334.      QuickInsert Sort Algorithm - a push from B$ASSN by Larry Stone
  2335.      
  2336.      One of the fastest, all purpose sort algorithms, is QuickSort.
  2337.      QuickSort is one of the sort routines supplied with the Microsoft
  2338.      program, "DEMOSORT.BAS". Speed is achieved by picking a random pivot
  2339.      point then moving every element bigger to one side of the random point
  2340.      and every value smaller to the other side. QuickSort then recursively
  2341.      calls itself from within its two areas of code that deal with those
  2342.      elements greater or smaller than the pivot point.
  2343.      
  2344.      I like QuickSort but, alas, there are a couple of limitations that
  2345.      prevent me from incorporating into my code.  The first is the fact
  2346.      that the pivot point is randomly selected. This means that the
  2347.      floating point library is loaded into the program. This is no small
  2348.      matter. The floating point library can add upwards of 10,000 bytes to
  2349.      one's final EXE size and, if the program is designed to avoid using
  2350.      floating point routines, this then becomes a prohibitive cost.
  2351.      
  2352.      The floating point library can be avoided by substituting a "homemade"
  2353.      random routine - one that uses LONG integers in lieu of real numbers.
  2354.      An outstanding replacement one could use is found in the book,
  2355.      "Microsoft QuickBASIC Programmer's Toolbox", by John Clark Craig.
  2356.      Craig's random generator is a QB version of two routines described in,
  2357.      "The Art of Computer Programming", Vol. 2, "Seminumerical Algorithms",
  2358.      by Donald Knuth. The random generator is an excellent replacement for
  2359.      QB's because it not only doesn't use floating point but also, it has a
  2360.      sequence length greater than 2^55 with a possible 256^83 possible
  2361.      sequences. That's an awful lot of random numbers!
  2362.      
  2363.      The real disadvantage to the QuickSort is the fact that it uses
  2364.      recursion. If there is a lot of data to sort, this recursive routine
  2365.      will blow the top of the stack. This can be overcome by setting a
  2366.      larger stack. Placing the statement, "CLEAR,,16384" at the top of the
  2367.      code will establish 16K of stack space. Conversely, "STACK 16384&"
  2368.      will do the same with PDS and the linker option, "/ST:16384", will do
  2369.      it if one compiles using PDQ. However, there is no free lunch.
  2370.      Increasing the stack size is accomplished by a comparable reduction in
  2371.      code and string space in DGROUP.
  2372.      
  2373.      Two other, quick sort routines may offer relief.  The WAVE sort,
  2374.      developed by Richard F. Ashwell for GW-BASIC is somewhat slower than
  2375.      the QuickSort but on large sorts, it really shines.  Another extremely
  2376.      fast sort that on average, is just a smidgen slower than the
  2377.      QuickSort, is the ripple sort algorithm that MicroHelp supplies with
  2378.      some of their tools. However, it seems logical that the absolute
  2379.      fastest sort should be an insertion sort - ie, sorting the data while
  2380.      it is gathered, intuitively, is faster than other techniques that
  2381.      requires two separate steps, a gathering followed by sorting.
  2382.      
  2383.      Unfortunately, BASIC insertion sorts are notoriously slow. They are
  2384.      
  2385.      The QBNews                                                     Page 39
  2386.      Volume  3, Number  1                                    March 29, 1992
  2387.  
  2388.      slow for two, related reasons. They require loops that must touch and
  2389.      compare array elements, one at a time, until the insertion point is
  2390.      located. This is generally accomplished by STEPping a FOR...NEXT loop
  2391.      in a negative direction, pushing each element "up the ladder" until
  2392.      the appropriate element is freed for insertion with new data. In three
  2393.      words, slow, slow, slow.
  2394.      
  2395.      "I-INSERT.BAS" overcomes the, up-to-now, inherent slowness of BASIC
  2396.      insertion sorts by incorporating two separate processes into its
  2397.      algorithm. The first part of the algorithm uses a modified binary
  2398.      search to quickly locate the appropriate insertion point. The binary
  2399.      search algorithm is not the generic binary search.  Although, like any
  2400.      binary search, it looks for a match between an array elements data and
  2401.      the data to be inserted, it also looks for the appropriate spot where
  2402.      the existing array data has greater value on the up-side and lesser
  2403.      value on the down-side. The test data used by I-INSERT contains 150
  2404.      random integers. On average, the binary search requires 5 steps into
  2405.      the array to locate the appropriate insertion point for each value
  2406.      inserted. The maximum number of steps required (for this data group)
  2407.      is seven and the minimum is one.
  2408.      
  2409.      The binary search is fast, not only because it minimizes the number of
  2410.      steps needed to locate the insertion point but also speeds along due
  2411.      to the nature of its architecture. If you look at the code, you will
  2412.      note that mathematics are limited to a single expression that adds the
  2413.      begin value to the ending value. Although the result of this is
  2414.      divided by two, the division is integer division which QB will compile
  2415.      as a shift instruction - "middle% = (begin% + ending%) \ 2".  The math
  2416.      like instructions, "begin% = middle% + 1" and "ending% = middle% - 1"
  2417.      are compiled as INC and DEC instructions to the CPU - again, very
  2418.      fast.  The search performs five tests. The first test is the
  2419.      conditional entry into the loop, "DO WHILE begin% <= ending%". Two of
  2420.      the tests are simple comparisons. One test isn't even a test but,
  2421.      rather, a fallthrough if the previous three tests within the loop are
  2422.      false. The slowest portion of the search is the first test. It tests
  2423.      two conditions and if the condition is met, then tests whether the
  2424.      insertion point is located.
  2425.      
  2426.      The second algorithm that comprises I-INSERT is the code that moves
  2427.      the existing data upwards in order to free the appropriate element for
  2428.      data insertion. It too, contains a single mathematic expression
  2429.      composed of a compiled SUB and IMUL instruction:
  2430.      
  2431.       "MoveBytes% = (LastElement% - middle%) * LEN(Arry%(Low%))"
  2432.      
  2433.      The actual moving of the array's elements is performed by a call to
  2434.      the routine, "QBMemCopy". This routine is an ALIAS for the QB
  2435.      procedure, "B$ASSN". B$ASSN copies a specified number of bytes from
  2436.      one memory location to another memory location in one, very quick
  2437.      move.  B$ASSN requires six parameters: FromSegment, FromOffset,
  2438.      BytesToCopy, ToSegment, ToOffset, and BytesToTransfer. All are
  2439.      integers and all must be passed by value.  Well, to speed things up
  2440.      just a wee bit more, the ALIAS for B$ASSN, "QBMemCopy", was declared
  2441.      using only four arguments: FromAddress, BytesFrom, ToAddress, and
  2442.      
  2443.      The QBNews                                                     Page 40
  2444.      Volume  3, Number  1                                    March 29, 1992
  2445.  
  2446.      BytesTo. Reduction in the number of arguments was accomplished by
  2447.      using the "SEG" directive which will push the segment and offset onto
  2448.      the stack.  Although the stack still has the same number of arguments,
  2449.      execution time is again improved because the code does not require a
  2450.      VARSEG and VARPTR instruction (QB is already aware of the variable's
  2451.      address so a simple SEG directive suffices). BytesFrom and BytesTo are
  2452.      still passed by value.
  2453.      
  2454.      I-INSERT does have some limitations. The first is that B$ASSN can only
  2455.      move 64K bytes at a time. And, as presently written, it can only move
  2456.      32K bytes. If you need to move more than 32K but less than 64K then
  2457.      make the following modification to the code that establishes MoveBytes:
  2458.      
  2459.       M& = 1& * (LastElement% - middle%) * LEN(Arry%(Low%))
  2460.       MoveBytes% = M& - 65536 * (M& > 32767)
  2461.      
  2462.      If you need to move more than 64K bytes then you must do it in
  2463.      "chunks".
  2464.      
  2465.      Because B$ASSN performs its copy in a forward direction, you must DIM
  2466.      another array of equal size to the array you will be inserting into
  2467.      (or equal to your largest "chunk"). QBMemCopy, the ALIAS for B$ASSN,
  2468.      first copies a block of memory, bounded by the insertion point to the
  2469.      last existing array element, to the scratch buffer or working array.
  2470.      From there, it copies back to the original array but places the data
  2471.      up one element from their original positions. Once this is
  2472.      accomplished, the new value is then inserted.
  2473.      
  2474.      A speed improvement and memory reduction can be achieved using the
  2475.      MicroHelp routine, MhMove in lieu of B$ASSN. MhMove is smart enough to
  2476.      realize that data is being moved within the same segment.  When MhMove
  2477.      "sees" this, it reverses the direction flag thereby, allowing for the
  2478.      copy to be performed only once. As a consequence, MhMove does not
  2479.      require the work array as a temporary scratch buffer which means that
  2480.      the memory allocated for B$ASSN to make its first copy to does not
  2481.      have to be allocated - hence, both a speed and memory improvement.
  2482.      
  2483.      Using I-INSERT's QuickInsert routine is as easy as eating apple pie.
  2484.      As your code reads in data, pass QuickInsert the value, the next array
  2485.      element that is available (LastElement%), and the array in which to
  2486.      insert the data. The work array or scratch buffer is DIM SHARED as
  2487.      TempSortArray%() and is not passed in the arguments list (If you use
  2488.      MhMove or a similar ASM routine then TempSortArray does not even need
  2489.      to be created.) That's all there is to it.
  2490.      
  2491.      It needs to be noted that the QuickInsert routine will not execute
  2492.      from within the QB or QBX environment. This is because neither
  2493.      environments will recognize the ALIAS for B$ASSN.  You must compile it
  2494.      to run it. Also, if you desire to test its speed against other sort
  2495.      procedures, to be fair, these procedures need to be timed from the
  2496.      point in which data is first copied into an array because QuickInsert
  2497.      is sorting while the array gets filled.
  2498.      
  2499.      By-the-way, B$ASSN, among other things, is used by QB to copy data
  2500.      
  2501.      The QBNews                                                     Page 41
  2502.      Volume  3, Number  1                                    March 29, 1992
  2503.  
  2504.      from TYPE to TYPE and fixed-length strings to variable length strings.
  2505.      As a consequence, a lot of QB internal string handling code will be
  2506.      included with your program if you use this routine. This won't be very
  2507.      noticeable if your program already uses string handling routines. But
  2508.      if it doesn't use strings then you should be aware that your EXE size
  2509.      will substantially increase by declaring and using B$ASSN.
  2510.      
  2511.      Two final notes. I was originally going to name the routine the "Stone
  2512.      Insert Sort" but false modesty prevented that. The second is a
  2513.      challenge. I challenge you, the reader, to discover other QB internals
  2514.      that can be applied in ways to perform insert sorts on strings and
  2515.      string arrays.
  2516.      
  2517.      SOURCE CODE FOR THIS ARTICLE CAN BE FOUND IN I-INSERT.ZIP
  2518.      
  2519.      ======================================================================
  2520.      Larry Stone is the author of the shareware file manager "SERVICES" and
  2521.      is also a frequent contributor to The QBNews. He can be contacted in
  2522.      care of this newsletter.
  2523.      ======================================================================
  2524.      
  2525.  
  2526.  
  2527.  
  2528.  
  2529.  
  2530.  
  2531.  
  2532.  
  2533.  
  2534.  
  2535.  
  2536.  
  2537.  
  2538.  
  2539.  
  2540.  
  2541.  
  2542.  
  2543.  
  2544.  
  2545.  
  2546.  
  2547.  
  2548.  
  2549.  
  2550.  
  2551.  
  2552.  
  2553.  
  2554.  
  2555.  
  2556.  
  2557.  
  2558.      The QBNews                                                     Page 42
  2559.      Volume  3, Number  1                                    March 29, 1992
  2560.  
  2561.  
  2562.  
  2563.      ----------------------------------------------------------------------
  2564.                             F u n   a n d   G a m e s
  2565.      ----------------------------------------------------------------------
  2566.  
  2567.      Having A Ball - Solution to 12 Ball Problem
  2568.      
  2569.      
  2570.      I've received exactly one entry into our little 12 ball problem
  2571.      contest. Luckily, it was correct. A hearty congratulations goes out to
  2572.      Jim Eccleston of North Vancouver, BC Canada. He wins our grand prize
  2573.      of a one year subscription to The QBNews. Here is how Jim did it.
  2574.      
  2575.      ----------------------------------------------------------------------
  2576.      Not very elegant but functional solution to "BALLS" in BALLS.BAS from
  2577.      Jim Eccleston
  2578.      North Vancouver, BC
  2579.      
  2580.      Accompanying info for solution program (in .BAS file also)
  2581.      
  2582.      Flowchart for weighing sequence structure above follows, with balls
  2583.      represented by alpha characters A thru L. ( I was less confused! )
  2584.      
  2585.      Letters shown in the balance pans. Outcome is Left, Balanced, Right
  2586.      L suffix in letter pairs = underweight, H suffix = overweight
  2587.      
  2588.      1st Level Weighing
  2589.                                     +------+------+
  2590.                                     | EFGH | IJKL |
  2591.                                     +------+------+
  2592.                                            |
  2593.                        +-------------------+---------------------+
  2594.      2nd Level         |                   |                     |
  2595.                 +------+------+      +-----+-----+        +------+------+
  2596.                 | IJKE | LABC |      | BCD | JKL |        | EFGI | HABC |
  2597.                 +------+------+      +-----+-----+        +------+------+
  2598.                  |     |     |        |    |    |          |     |     |
  2599.      3rd Level   |     |     |        |    |    |          |    /      |
  2600.              +---+---+ | +---+---+    |    |    |    +---+---+ | +---+---+
  2601.              | J | K | | | E | A |    |    |    |    | F | G | | | I | A |
  2602.              +---+---+ | +---+---+    |    |    |    +---+---+ | +---+---+
  2603.              KL IL JL  |  EH LL *     |    |    |    GL EL FL  |  IH HL  *
  2604.                        |             /     |     \              \
  2605.                    +---+---+        /      |      \          +---+---+
  2606.                    | G | H |       /       |       \         | K | L |
  2607.                    +---+---+      /        |        \        +---+---+
  2608.                   GH  FH  HH     |         |         |       KH  JH  LH
  2609.                           +---+---+    +---+---+    +---+---+
  2610.                           | C | D |    | A | L |    | C | D |
  2611.                           +---+---+    +---+---+    +---+---+
  2612.                           CH BH DH     AH  *  AL    DL BL CL
  2613.       * = Innaplicable
  2614.      
  2615.      
  2616.      
  2617.      
  2618.      The QBNews                                                     Page 43
  2619.      Volume  3, Number  1                                    March 29, 1992
  2620.  
  2621.      Find above a solution to the Having a Ball problem which I'm sure
  2622.      will arrive far too late from the frozen north to stand a chance at
  2623.      the prize unless there's a Canadian section  :)  , but the feature
  2624.      is a great addition and I hope it is continued. The problem reminds
  2625.      me of one I saw in the 60's that used a set of base 3 weights.
  2626.      
  2627.      Am sending also a small piece of video chewing gum you may want to
  2628.      use for entertainment purposes or your readers might enjoy.
  2629.      
  2630.           Best Wishes for this New Year and many thanks for a job
  2631.           exceedingly well done.
  2632.                                      Jim Eccleston.
  2633.      
  2634.      ----------------------------------------------------------------------
  2635.      
  2636.      All files are contained in the file BALLS.ZIP. Jim's solution is in
  2637.      the file WINNERS.BAS while Charles Graham's solution (originator of
  2638.      the problem) is in the file BALLS.BAS. I've also included a small
  2639.      program Jim sent in with his entry that I think is quite interesting.
  2640.      It is in the file WORMS.BAS. Load it into QB and enjoy.
  2641.      
  2642.  
  2643.  
  2644.  
  2645.  
  2646.  
  2647.  
  2648.  
  2649.  
  2650.  
  2651.  
  2652.  
  2653.  
  2654.  
  2655.  
  2656.  
  2657.  
  2658.  
  2659.  
  2660.  
  2661.  
  2662.  
  2663.  
  2664.  
  2665.  
  2666.  
  2667.  
  2668.  
  2669.  
  2670.  
  2671.  
  2672.  
  2673.  
  2674.  
  2675.      The QBNews                                                     Page 44
  2676.      The QBNews Master Index for Volume 2                    March 28, 1992 
  2677.               Article Name                                      Vol  Issue
  2678.      ======================================================================
  2679.      
  2680.      
  2681.      Algorithms               
  2682.         Cardan's Method for Solving Cubes......................  2     3
  2683.         Improved Cloning Algorithm.............................  2     2
  2684.         Playing Around with Random Numbers.....................  2     1
  2685.         Reversing Color Attributes.............................  2     1
  2686.      
  2687.      Assembler                
  2688.         Event-Driven Mouse Support Library.....................  2     3
  2689.         Fast Screen Printing...................................  2     2
  2690.         Pop-Up Windows.........................................  2     4
  2691.         Setting Error Levels with QB...........................  2     1
  2692.      
  2693.      CALL INTERRUPT           
  2694.         A Bug Free CALL INTERRUPT..............................  2     3
  2695.         Add BASIC 7's DIR$ Routine to your QB Programs.........  2     2
  2696.         Everything You Wanted To Know About a Program..........  2     1
  2697.         How to Copy Files with QB..............................  2     2
  2698.      
  2699.      Charles Graham           
  2700.         ASCII Art -- A Piece of Computer History...............  2     2
  2701.         Having a Ball..........................................  2     4
  2702.         How I Came to Know and Love ANSI.SYS...................  2     1
  2703.         Lines with Style.......................................  2     3
  2704.      
  2705.      Christy Gemmel           
  2706.         Fast Screen Printing...................................  2     2
  2707.         Pop-Up Windows.........................................  2     4
  2708.      
  2709.      Communications           
  2710.         A Look at Crescent Software's PDQComm..................  2     2
  2711.         PDQComm 2.5 from Crescent Software.....................  2     1
  2712.         Using COM3 and COM4 with QB............................  2     4
  2713.      
  2714.      Copyrights               
  2715.         Intellectual Property Protection.......................  2     1
  2716.      
  2717.      Cornel Huth              
  2718.         A Bug Free CALL INTERRUPT..............................  2     3
  2719.      
  2720.      Daniel R. Berry          
  2721.         Working with the Rodent................................  2     2
  2722.      
  2723.      David Cleary             
  2724.         Add BASIC 7's DIR$ Routine to your QB Programs.........  2     2
  2725.         Having a Ball..........................................  2     4
  2726.         How to Copy Files with QB..............................  2     2
  2727.         Setting Error Levels with QB...........................  2     1
  2728.         Special Preview of Visual Basic........................  2     2
  2729.      
  2730.      David Postler            
  2731.         Intellectual Property Protection.......................  2     1
  2732.      The QBNews Master Index for Volume 2                    March 28, 1992 
  2733.               Article Name                                      Vol  Issue
  2734.      ======================================================================
  2735.      
  2736.      
  2737.      David Rice               
  2738.         Create Bar Charts in Text Mode with QB.................  2     2
  2739.         Create Pie Charts with QB..............................  2     2
  2740.      
  2741.      Dick Dennison            
  2742.         Using COM3 and COM4 with QB............................  2     4
  2743.      
  2744.      Ethan Winer              
  2745.         QB's Hidden Data Copying...............................  2     3
  2746.      
  2747.      File IO                  
  2748.         Add BASIC 7's DIR$ Routine to your QB Programs.........  2     2
  2749.         Getting and Setting File Attributes....................  2     1
  2750.         How to Copy Files with QB..............................  2     2
  2751.      
  2752.      Fred Sexton Jr.          
  2753.         Manipulating Sprites in SCREEN 13......................  2     3
  2754.      
  2755.      Fun and Games            
  2756.         ASCII Art -- A Piece of Computer History...............  2     2
  2757.         Having a Ball..........................................  2     4
  2758.         Lines with Style.......................................  2     3
  2759.      
  2760.      Graphics                 
  2761.         A Graphics Mouse Cursor Design System..................  2     2
  2762.         Create Pie Charts with QB..............................  2     2
  2763.         Fonts in a Can.........................................  2     3
  2764.         Lines with Style.......................................  2     3
  2765.         Manipulating Sprites in SCREEN 13......................  2     3
  2766.         Reading Print Shop Graphics in QB......................  2     1
  2767.      
  2768.      J. D. Hildebrand         
  2769.         Spill the Wine.........................................  2     3
  2770.      
  2771.      James Young              
  2772.         Playing Around with Random Numbers.....................  2     1
  2773.      
  2774.      Jim Harre                
  2775.         A Look at Crescent Software's PDQComm..................  2     2
  2776.      
  2777.      John Richard De Palma    
  2778.         BASICZen...............................................  2     2
  2779.      
  2780.      Keith Rolland            
  2781.         Everything You Wanted To Know About a Program..........  2     1
  2782.      
  2783.      Larry Stone              
  2784.         Fonts in a Can.........................................  2     3
  2785.         Improved Cloning Algorithm.............................  2     2
  2786.      The QBNews Master Index for Volume 2                    March 28, 1992 
  2787.               Article Name                                      Vol  Issue
  2788.      ======================================================================
  2789.      
  2790.      
  2791.      Larry Stone              
  2792.         Lines with Style.......................................  2     3
  2793.      
  2794.      Mike Welch               
  2795.         Introduction to QuickSHARE.............................  2     1
  2796.         Reading Print Shop Graphics in QB......................  2     1
  2797.      
  2798.      Monte Ferguson           
  2799.         Detecting Desqview from QB.............................  2     1
  2800.      
  2801.      Mouse                    
  2802.         A Graphics Mouse Cursor Design System..................  2     2
  2803.         Event-Driven Mouse Support Library.....................  2     3
  2804.         Working with the Rodent................................  2     2
  2805.      
  2806.      QBNews Professional Library
  2807.         Event-Driven Mouse Support Library.....................  2     3
  2808.         Fast Screen Printing...................................  2     2
  2809.         Pop-Up Windows.........................................  2     4
  2810.      
  2811.      Ray Crumrine             
  2812.         The UEVENT Bug.........................................  2     4
  2813.      
  2814.      Richard Jones            
  2815.         Cardan's Method for Solving Cubes......................  2     3
  2816.      
  2817.      Richard Randles          
  2818.         Getting and Setting Bits...............................  2     1
  2819.      
  2820.      Rick Cooper              
  2821.         Getting and Setting File Attributes....................  2     1
  2822.         Reversing Color Attributes.............................  2     1
  2823.      
  2824.      Screen IO                
  2825.         Create Bar Charts in Text Mode with QB.................  2     2
  2826.         Fast Screen Printing...................................  2     2
  2827.         How I Came to Know and Love ANSI.SYS...................  2     1
  2828.         Pop-Up Windows.........................................  2     4
  2829.         Reversing Color Attributes.............................  2     1
  2830.      
  2831.      Shareware                
  2832.         Introduction to QuickSHARE.............................  2     1
  2833.      
  2834.      Source Code              
  2835.         A Bug Free CALL INTERRUPT..............................  2     3
  2836.         Add BASIC 7's DIR$ Routine to your QB Programs.........  2     2
  2837.         Cardan's Method for Solving Cubes......................  2     3
  2838.         Create Bar Charts in Text Mode with QB.................  2     2
  2839.         Create Pie Charts with QB..............................  2     2
  2840.      The QBNews Master Index for Volume 2                    March 28, 1992 
  2841.               Article Name                                      Vol  Issue
  2842.      ======================================================================
  2843.      
  2844.      
  2845.      Source Code              
  2846.         Creating Smaller QB EXEcutables........................  2     1
  2847.         Detecting Desqview from QB.............................  2     1
  2848.         Event-Driven Mouse Support Library.....................  2     3
  2849.         Everything You Wanted To Know About a Program..........  2     1
  2850.         Fonts in a Can.........................................  2     3
  2851.         Getting and Setting Bits...............................  2     1
  2852.         Getting and Setting File Attributes....................  2     1
  2853.         How I Came to Know and Love ANSI.SYS...................  2     1
  2854.         How to Copy Files with QB..............................  2     2
  2855.         Improved Cloning Algorithm.............................  2     2
  2856.         Lines with Style.......................................  2     3
  2857.         Manipulating Sprites in SCREEN 13......................  2     3
  2858.         Playing Around with Random Numbers.....................  2     1
  2859.         Reading Print Shop Graphics in QB......................  2     1
  2860.         Reversing Color Attributes.............................  2     1
  2861.         Setting Error Levels with QB...........................  2     1
  2862.         Using COM3 and COM4 with QB............................  2     4
  2863.         Working with the Rodent................................  2     2
  2864.      
  2865.      T. G. Muench             
  2866.         Creating Smaller QB EXEcutables........................  2     1
  2867.      
  2868.      Tony Elliot              
  2869.         Event-Driven Mouse Support Library.....................  2     3
  2870.      
  2871.      Tools                    
  2872.         A Look at Crescent Software's PDQComm..................  2     2
  2873.         Custom Control Factory for MS Visual Basic.............  2     2
  2874.         PDQComm 2.5 from Crescent Software.....................  2     1
  2875.      
  2876.      Tricks and Tips          
  2877.         Creating Smaller QB EXEcutables........................  2     1
  2878.         QB's Hidden Data Copying...............................  2     3
  2879.         The UEVENT Bug.........................................  2     4
  2880.      
  2881.      View Print               
  2882.         BASICZen...............................................  2     2
  2883.         Spill the Wine.........................................  2     3
  2884.      
  2885.      Visual Basic             
  2886.         Custom Control Factory for MS Visual Basic.............  2     2
  2887.         Special Preview of Visual Basic........................  2     2
  2888.      
  2889.      Warren G. Lieuallen      
  2890.         A Graphics Mouse Cursor Design System..................  2     2
  2891.  
  2892.